diff --git a/artifactory/commands/packagemanagerlogin/packagemanagerlogin.go b/artifactory/commands/packagemanagerlogin/packagemanagerlogin.go index eb00804c3..59b315ec3 100644 --- a/artifactory/commands/packagemanagerlogin/packagemanagerlogin.go +++ b/artifactory/commands/packagemanagerlogin/packagemanagerlogin.go @@ -21,7 +21,7 @@ import ( "github.com/jfrog/jfrog-client-go/utils/log" "golang.org/x/exp/maps" "net/url" - "sort" + "slices" ) // packageManagerToRepositoryPackageType maps project types to corresponding Artifactory repository package types. @@ -52,6 +52,8 @@ type PackageManagerLoginCommand struct { packageManager project.ProjectType // repoName is the name of the repository used for configuration. repoName string + // projectKey is the JFrog Project key in JFrog Platform. + projectKey string // serverDetails contains Artifactory server configuration. serverDetails *config.ServerDetails // commandName specifies the command for this instance. @@ -70,8 +72,9 @@ func NewPackageManagerLoginCommand(packageManager project.ProjectType) *PackageM // GetSupportedPackageManagersList returns a sorted list of supported package managers. func GetSupportedPackageManagersList() []project.ProjectType { allSupportedPackageManagers := maps.Keys(packageManagerToRepositoryPackageType) - sort.Slice(allSupportedPackageManagers, func(i, j int) bool { - return allSupportedPackageManagers[i] < allSupportedPackageManagers[j] + // Sort keys based on their natural enum order + slices.SortFunc(allSupportedPackageManagers, func(a, b project.ProjectType) int { + return int(a) - int(b) }) return allSupportedPackageManagers } @@ -81,19 +84,6 @@ func IsSupportedPackageManager(packageManager project.ProjectType) bool { return exists } -// packageManagerToPackageType maps project types to corresponding Artifactory package types (e.g., npm, pypi). -func packageManagerToPackageType(packageManager project.ProjectType) (string, error) { - // Retrieve the package type from the map. - if packageType, exists := packageManagerToRepositoryPackageType[packageManager]; exists { - return packageType, nil - } - if !IsSupportedPackageManager(packageManager) { - return "", errorutils.CheckErrorf("unsupported package type for package manager: %s", packageManager) - } - // Return an error if the package manager is unsupported. - return packageManagerToRepositoryPackageType[packageManager], nil -} - // CommandName returns the name of the login command. func (pmlc *PackageManagerLoginCommand) CommandName() string { return pmlc.commandName @@ -110,8 +100,24 @@ func (pmlc *PackageManagerLoginCommand) ServerDetails() (*config.ServerDetails, return pmlc.serverDetails, nil } +// SetRepoName assigns the repository name to the command. +func (pmlc *PackageManagerLoginCommand) SetRepoName(repoName string) *PackageManagerLoginCommand { + pmlc.repoName = repoName + return pmlc +} + +// SetProjectKey assigns the project key to the command. +func (pmlc *PackageManagerLoginCommand) SetProjectKey(projectKey string) *PackageManagerLoginCommand { + pmlc.projectKey = projectKey + return pmlc +} + // Run executes the configuration method corresponding to the package manager specified for the command. func (pmlc *PackageManagerLoginCommand) Run() (err error) { + if IsSupportedPackageManager(pmlc.packageManager) { + return errorutils.CheckErrorf("unsupported package manager: %s", pmlc.packageManager) + } + if pmlc.repoName == "" { // Prompt the user to select a virtual repository that matches the package manager. if err = pmlc.promptUserToSelectRepository(); err != nil { @@ -147,15 +153,11 @@ func (pmlc *PackageManagerLoginCommand) Run() (err error) { } // promptUserToSelectRepository prompts the user to select a compatible virtual repository. -func (pmlc *PackageManagerLoginCommand) promptUserToSelectRepository() error { - // Map the package manager to its corresponding package type. - packageType, err := packageManagerToPackageType(pmlc.packageManager) - if err != nil { - return err - } +func (pmlc *PackageManagerLoginCommand) promptUserToSelectRepository() (err error) { repoFilterParams := services.RepositoriesFilterParams{ RepoType: utils.Virtual.String(), - PackageType: packageType, + PackageType: packageManagerToRepositoryPackageType[pmlc.packageManager], + ProjectKey: pmlc.projectKey, } // Prompt for repository selection based on filter parameters. diff --git a/artifactory/commands/packagemanagerlogin/packagemanagerlogin_test.go b/artifactory/commands/packagemanagerlogin/packagemanagerlogin_test.go index 8bb95abde..9783e8133 100644 --- a/artifactory/commands/packagemanagerlogin/packagemanagerlogin_test.go +++ b/artifactory/commands/packagemanagerlogin/packagemanagerlogin_test.go @@ -13,6 +13,7 @@ import ( clientTestUtils "github.com/jfrog/jfrog-client-go/utils/tests" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/exp/slices" "os" "os/exec" "path/filepath" @@ -52,6 +53,13 @@ func createTestPackageManagerLoginCommand(packageManager project.ProjectType) *P return cmd } +func TestPackageManagerLoginCommand_NotSupported(t *testing.T) { + notSupportedLoginCmd := createTestPackageManagerLoginCommand(project.Cocoapods) + err := notSupportedLoginCmd.Run() + assert.Error(t, err) + assert.ErrorContains(t, err, "unsupported package manager") +} + func TestPackageManagerLoginCommand_Npm(t *testing.T) { // Create a temporary directory to act as the environment's npmrc file location. tempDir := t.TempDir() @@ -381,3 +389,20 @@ func testBuildToolLoginCommandConfigureDotnetNuget(t *testing.T, packageManager }) } } + +func TestGetSupportedPackageManagersList(t *testing.T) { + result := GetSupportedPackageManagersList() + // Check that Go is before Pip, and Pip is before Npm using GreaterOrEqual + assert.GreaterOrEqual(t, slices.Index(result, project.Pip), slices.Index(result, project.Go), "Go should come before Pip") + assert.GreaterOrEqual(t, slices.Index(result, project.Npm), slices.Index(result, project.Pip), "Pip should come before Npm") +} + +func TestIsSupportedPackageManager(t *testing.T) { + // Test valid package managers + for pm := range packageManagerToRepositoryPackageType { + assert.True(t, IsSupportedPackageManager(pm), "Package manager %s should be supported", pm) + } + + // Test unsupported package manager + assert.False(t, IsSupportedPackageManager(project.Cocoapods), "Package manager Cocoapods should not be supported") +} diff --git a/common/project/projectconfig_test.go b/common/project/projectconfig_test.go new file mode 100644 index 000000000..92bd849e6 --- /dev/null +++ b/common/project/projectconfig_test.go @@ -0,0 +1,30 @@ +package project + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestFromString(t *testing.T) { + // Test valid conversions + tests := []struct { + input string + expected ProjectType + }{ + {"go", Go}, + {"pip", Pip}, + {"npm", Npm}, + {"pnpm", Pnpm}, + } + + for _, test := range tests { + t.Run(test.input, func(t *testing.T) { + result := FromString(test.input) + assert.Equal(t, test.expected, result, "For input %s, expected %v but got %v", test.input, test.expected, result) + }) + } + + // Test invalid conversion + result := FromString("InvalidProject") + assert.Equal(t, ProjectType(-1), result, "Expected -1 for invalid project type") +}