Skip to content

Commit 02252d2

Browse files
committed
Improve upload archive progress bar
Signed-off-by: Michael Sverdlov <[email protected]>
1 parent 89cdb97 commit 02252d2

File tree

4 files changed

+133
-12
lines changed

4 files changed

+133
-12
lines changed

artifactory/commands/dotnet/dotnetcommand.go

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"fmt"
66
"github.com/jfrog/build-info-go/build"
77
"github.com/jfrog/build-info-go/build/utils/dotnet"
8-
"github.com/jfrog/gofrog/io"
8+
frogio "github.com/jfrog/gofrog/io"
99
commonBuild "github.com/jfrog/jfrog-cli-core/v2/common/build"
1010
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
1111
"github.com/jfrog/jfrog-client-go/auth"
@@ -19,7 +19,7 @@ import (
1919
)
2020

2121
const (
22-
SourceName = "JFrogCli"
22+
SourceName = "JFrogArtifactory"
2323
configFilePattern = "jfrog.cli.nuget."
2424

2525
dotnetTestError = `the command failed with an error.
@@ -159,21 +159,44 @@ func changeWorkingDir(newWorkingDir string) (string, error) {
159159
return newWorkingDir, errorutils.CheckError(err)
160160
}
161161

162-
// Runs nuget sources add command
163-
func AddSourceToNugetConfig(cmdType dotnet.ToolchainType, configFileName, sourceUrl, user, password string) error {
162+
// Runs nuget/dotnet source add command
163+
func AddSourceToNugetConfig(cmdType dotnet.ToolchainType, sourceUrl, user, password string) error {
164164
cmd, err := dotnet.CreateDotnetAddSourceCmd(cmdType, sourceUrl)
165165
if err != nil {
166166
return err
167167
}
168168

169169
flagPrefix := cmdType.GetTypeFlagPrefix()
170-
cmd.CommandFlags = append(cmd.CommandFlags, flagPrefix+"configfile", configFileName)
171170
cmd.CommandFlags = append(cmd.CommandFlags, flagPrefix+"name", SourceName)
172171
cmd.CommandFlags = append(cmd.CommandFlags, flagPrefix+"username", user)
173172
cmd.CommandFlags = append(cmd.CommandFlags, flagPrefix+"password", password)
174-
output, err := io.RunCmdOutput(cmd)
175-
log.Debug("'Add sources' command executed. Output:", output)
176-
return err
173+
stdOut, errorOut, _, err := frogio.RunCmdWithOutputParser(cmd, false)
174+
if err != nil {
175+
return fmt.Errorf("failed to add source: %w\n%s", err, strings.TrimSpace(stdOut+errorOut))
176+
}
177+
return nil
178+
}
179+
180+
// Runs nuget/dotnet source remove command
181+
func RemoveSourceFromNugetConfigIfExists(cmdType dotnet.ToolchainType) error {
182+
cmd, err := dotnet.NewToolchainCmd(cmdType)
183+
if err != nil {
184+
return err
185+
}
186+
if cmdType == dotnet.DotnetCore {
187+
cmd.Command = append(cmd.Command, "nuget", "remove", "source", SourceName)
188+
} else {
189+
cmd.Command = append(cmd.Command, "sources", "remove")
190+
cmd.CommandFlags = append(cmd.CommandFlags, "-name", SourceName)
191+
}
192+
stdOut, stdErr, _, err := frogio.RunCmdWithOutputParser(cmd, false)
193+
if err != nil {
194+
if strings.Contains(stdOut+stdErr, "Unable to find") {
195+
return nil
196+
}
197+
return fmt.Errorf("failed to remove source: %w\n%s", err, strings.TrimSpace(stdOut+stdErr))
198+
}
199+
return nil
177200
}
178201

179202
// Checks if the user provided input such as -configfile flag or -Source flag.
@@ -266,7 +289,7 @@ func InitNewConfig(configDirPath, repoName string, server *config.ServerDetails,
266289

267290
// Adds a source to the nuget config template
268291
func addSourceToNugetTemplate(configFile *os.File, server *config.ServerDetails, useNugetV2 bool, repoName string) error {
269-
sourceUrl, user, password, err := getSourceDetails(server, repoName, useNugetV2)
292+
sourceUrl, user, password, err := GetSourceDetails(server, repoName, useNugetV2)
270293
if err != nil {
271294
return err
272295
}
@@ -282,7 +305,7 @@ func addSourceToNugetTemplate(configFile *os.File, server *config.ServerDetails,
282305
return err
283306
}
284307

285-
func getSourceDetails(details *config.ServerDetails, repoName string, useNugetV2 bool) (sourceURL, user, password string, err error) {
308+
func GetSourceDetails(details *config.ServerDetails, repoName string, useNugetV2 bool) (sourceURL, user, password string, err error) {
286309
var u *url.URL
287310
u, err = url.Parse(details.ArtifactoryUrl)
288311
if errorutils.CheckError(err) != nil {

artifactory/commands/dotnet/dotnetcommand_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,14 @@ func TestGetSourceDetails(t *testing.T) {
129129
Password: "pass",
130130
}
131131
repoName := "repo-name"
132-
url, user, pass, err := getSourceDetails(server, repoName, false)
132+
url, user, pass, err := GetSourceDetails(server, repoName, false)
133133
assert.NoError(t, err)
134134
assert.Equal(t, "user", user)
135135
assert.Equal(t, "pass", pass)
136136
assert.Equal(t, "https://server.com/artifactory/api/nuget/v3/repo-name", url)
137137
server.Password = ""
138138
server.AccessToken = "abc123"
139-
url, user, pass, err = getSourceDetails(server, repoName, true)
139+
url, user, pass, err = GetSourceDetails(server, repoName, true)
140140
assert.Equal(t, "user", user)
141141
assert.Equal(t, "abc123", pass)
142142
assert.NoError(t, err)

artifactory/commands/packagemanagerlogin/packagemanagerlogin.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package packagemanagerlogin
22

33
import (
44
"fmt"
5+
bidotnet "github.com/jfrog/build-info-go/build/utils/dotnet"
56
biutils "github.com/jfrog/build-info-go/utils"
7+
"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/dotnet"
68
gocommands "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/golang"
79
pythoncommands "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/python"
810
"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/repository"
@@ -47,6 +49,8 @@ func packageManagerToPackageType(packageManager project.ProjectType) (string, er
4749
return repository.Pypi, nil
4850
case project.Go:
4951
return repository.Go, nil
52+
case project.Nuget, project.Dotnet:
53+
return repository.Nuget, nil
5054
default:
5155
return "", errorutils.CheckErrorf("unsupported package manager: %s", packageManager)
5256
}
@@ -89,6 +93,8 @@ func (pmlc *PackageManagerLoginCommand) Run() (err error) {
8993
err = pmlc.configurePoetry()
9094
case project.Go:
9195
err = pmlc.configureGo()
96+
case project.Nuget, project.Dotnet:
97+
err = pmlc.configureDotnetNuget()
9298
default:
9399
err = errorutils.CheckErrorf("unsupported package manager: %s", pmlc.packageManager)
94100
}
@@ -205,3 +211,32 @@ func (pmlc *PackageManagerLoginCommand) configureGo() error {
205211
}
206212
return biutils.RunGo([]string{"env", "-w", "GOPROXY=" + repoWithCredsUrl}, "")
207213
}
214+
215+
// configureDotnetNuget configures NuGet or .NET Core to use the specified Artifactory repository with credentials.
216+
// Adds the repository source to the NuGet configuration file, using appropriate credentials for authentication.
217+
// The following command is run for dotnet:
218+
//
219+
// dotnet nuget add source --name <JFrog-Artifactory> "https://acme.jfrog.io/artifactory/api/nuget/{repository-name}" --username <your-username> --password <your-password>
220+
//
221+
// For NuGet:
222+
//
223+
// nuget sources add -Name <JFrog-Artifactory> -Source "https://acme.jfrog.io/artifactory/api/nuget/{repository-name}" -Username <your-username> -Password <your-password>
224+
func (pmlc *PackageManagerLoginCommand) configureDotnetNuget() error {
225+
// Retrieve repository URL and credentials for NuGet or .NET Core.
226+
sourceUrl, user, password, err := dotnet.GetSourceDetails(pmlc.serverDetails, pmlc.repoName, false)
227+
if err != nil {
228+
return err
229+
}
230+
231+
// Determine the appropriate toolchain type (NuGet or .NET Core).
232+
toolchainType := bidotnet.DotnetCore
233+
if pmlc.packageManager == project.Nuget {
234+
toolchainType = bidotnet.Nuget
235+
}
236+
err = dotnet.RemoveSourceFromNugetConfigIfExists(toolchainType)
237+
if err != nil {
238+
return err
239+
}
240+
// Add the repository as a source in the NuGet configuration with credentials for authentication.
241+
return dotnet.AddSourceToNugetConfig(toolchainType, sourceUrl, user, password)
242+
}

artifactory/commands/packagemanagerlogin/packagemanagerlogin_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package packagemanagerlogin
22

33
import (
44
"fmt"
5+
"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/dotnet"
56
cmdutils "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/utils"
67
"github.com/jfrog/jfrog-cli-core/v2/common/project"
78
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
@@ -326,3 +327,65 @@ func TestPackageManagerLoginCommand_Go(t *testing.T) {
326327
})
327328
}
328329
}
330+
331+
func TestBuildToolLoginCommand_configureNuget(t *testing.T) {
332+
testBuildToolLoginCommandConfigureDotnetNuget(t, project.Nuget)
333+
}
334+
335+
func TestBuildToolLoginCommand_configureDotnet(t *testing.T) {
336+
testBuildToolLoginCommandConfigureDotnetNuget(t, project.Dotnet)
337+
}
338+
339+
func testBuildToolLoginCommandConfigureDotnetNuget(t *testing.T, packageManager project.ProjectType) {
340+
// Retrieve the home directory and construct the NuGet.config file path.
341+
homeDir, err := os.UserHomeDir()
342+
assert.NoError(t, err)
343+
var nugetConfigDir string
344+
if io.IsWindows() {
345+
nugetConfigDir = "AppData"
346+
} else if packageManager == project.Nuget {
347+
nugetConfigDir = ".config"
348+
} else if packageManager == project.Dotnet {
349+
nugetConfigDir = ".nuget"
350+
}
351+
nugetConfigFilePath := filepath.Join(homeDir, nugetConfigDir, "NuGet", "NuGet.config")
352+
353+
// Back up the existing NuGet.config and ensure restoration after the test.
354+
restoreNugetConfigFunc, err := ioutils.BackupFile(nugetConfigFilePath, ".nuget.config.backup")
355+
assert.NoError(t, err)
356+
defer func() {
357+
assert.NoError(t, restoreNugetConfigFunc())
358+
}()
359+
360+
nugetLoginCmd := createTestPackageManagerLoginCommand(packageManager)
361+
362+
for _, testCase := range testCases {
363+
t.Run(testCase.name, func(t *testing.T) {
364+
// Set up server details for the current test case's authentication type.
365+
nugetLoginCmd.serverDetails.SetUser(testCase.user)
366+
nugetLoginCmd.serverDetails.SetPassword(testCase.password)
367+
nugetLoginCmd.serverDetails.SetAccessToken(testCase.accessToken)
368+
369+
// Run the login command and ensure no errors occur.
370+
if !assert.NoError(t, nugetLoginCmd.Run()) {
371+
t.FailNow()
372+
}
373+
374+
// Validate that the repository URL was set correctly in Nuget.config.
375+
// Read the contents of the temporary Poetry config file.
376+
nugetConfigContentBytes, err := os.ReadFile(nugetConfigFilePath)
377+
assert.NoError(t, err)
378+
nugetConfigContent := string(nugetConfigContentBytes)
379+
380+
assert.Contains(t, nugetConfigContent, fmt.Sprintf("add key=\"%s\" value=\"https://acme.jfrog.io/artifactory/api/nuget/v3/test-repo\"", dotnet.SourceName))
381+
382+
if testCase.accessToken != "" {
383+
// Validate token-based authentication (The token is encoded so we can't test it)
384+
assert.Contains(t, nugetConfigContent, fmt.Sprintf("<add key=\"Username\" value=\"%s\" />", auth.ExtractUsernameFromAccessToken(testCase.accessToken)))
385+
} else if testCase.user != "" && testCase.password != "" {
386+
// Validate basic nugetConfigContent with user and password. (The password is encoded so we can't test it)
387+
assert.Contains(t, nugetConfigContent, fmt.Sprintf("<add key=\"Username\" value=\"%s\" />", testCase.user))
388+
}
389+
})
390+
}
391+
}

0 commit comments

Comments
 (0)