diff --git a/artifactory/commands/transferfiles/transfer.go b/artifactory/commands/transferfiles/transfer.go index a08d04562..4e2324c48 100644 --- a/artifactory/commands/transferfiles/transfer.go +++ b/artifactory/commands/transferfiles/transfer.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "github.com/jfrog/gofrog/safeconvert" + "github.com/jfrog/jfrog-client-go/artifactory/services" "os" "os/signal" "path/filepath" @@ -342,11 +343,11 @@ func (tdc *TransferFilesCommand) NewTransferDataPreChecksRunner() (runner *prech if err != nil { return } - localRepos, err := utils.GetFilteredRepositoriesByNameAndType(serviceManager, tdc.includeReposPatterns, tdc.excludeReposPatterns, utils.Local) + localRepos, err := utils.GetFilteredRepositoriesWithFilterParams(serviceManager, tdc.includeReposPatterns, tdc.excludeReposPatterns, services.RepositoriesFilterParams{RepoType: utils.Local.String()}) if err != nil { return } - federatedRepos, err := utils.GetFilteredRepositoriesByNameAndType(serviceManager, tdc.includeReposPatterns, tdc.excludeReposPatterns, utils.Federated) + federatedRepos, err := utils.GetFilteredRepositoriesWithFilterParams(serviceManager, tdc.includeReposPatterns, tdc.excludeReposPatterns, services.RepositoriesFilterParams{RepoType: utils.Federated.String()}) if err != nil { return } @@ -586,11 +587,11 @@ func (tdc *TransferFilesCommand) getAllLocalRepos(serverDetails *config.ServerDe } excludeRepoPatternsWithBuildInfo := tdc.excludeReposPatterns excludeRepoPatternsWithBuildInfo = append(excludeRepoPatternsWithBuildInfo, "*-build-info") - localRepos, err := utils.GetFilteredRepositoriesByNameAndType(serviceManager, tdc.includeReposPatterns, excludeRepoPatternsWithBuildInfo, utils.Local) + localRepos, err := utils.GetFilteredRepositoriesWithFilterParams(serviceManager, tdc.includeReposPatterns, excludeRepoPatternsWithBuildInfo, services.RepositoriesFilterParams{RepoType: utils.Local.String()}) if err != nil { return []string{}, []string{}, err } - federatedRepos, err := utils.GetFilteredRepositoriesByNameAndType(serviceManager, tdc.includeReposPatterns, excludeRepoPatternsWithBuildInfo, utils.Federated) + federatedRepos, err := utils.GetFilteredRepositoriesWithFilterParams(serviceManager, tdc.includeReposPatterns, excludeRepoPatternsWithBuildInfo, services.RepositoriesFilterParams{RepoType: utils.Federated.String()}) if err != nil { return []string{}, []string{}, err } diff --git a/artifactory/utils/commandsummary/buildinfosummary.go b/artifactory/utils/commandsummary/buildinfosummary.go index 9861c723c..07bb7d35b 100644 --- a/artifactory/utils/commandsummary/buildinfosummary.go +++ b/artifactory/utils/commandsummary/buildinfosummary.go @@ -209,6 +209,9 @@ func (bis *BuildInfoSummary) createArtifactsTree(module *buildInfo.Module) strin } artifactTreePath := path.Join(artifact.OriginalDeploymentRepo, artifact.Path) artifactsTree.AddFile(artifactTreePath, artifactUrlInArtifactory) + if artifactsTree.IsTreeExceedsMax() { + return "" + } } return artifactsTree.String() } diff --git a/artifactory/utils/commandsummary/uploadsummary.go b/artifactory/utils/commandsummary/uploadsummary.go index 1aa683c36..cccaca2d8 100644 --- a/artifactory/utils/commandsummary/uploadsummary.go +++ b/artifactory/utils/commandsummary/uploadsummary.go @@ -55,6 +55,9 @@ func (us *UploadSummary) generateFileTreeMarkdown() string { us.uploadTree = utils.NewFileTree() for _, uploadResult := range us.uploadedArtifacts.Results { us.uploadTree.AddFile(uploadResult.TargetPath, us.buildUiUrl(uploadResult.TargetPath)) + if us.uploadTree.IsTreeExceedsMax() { + return "" + } } return us.uploadTree.String() } diff --git a/artifactory/utils/filetree.go b/artifactory/utils/filetree.go index 4b6ae17ff..fafd5c485 100644 --- a/artifactory/utils/filetree.go +++ b/artifactory/utils/filetree.go @@ -12,9 +12,8 @@ var maxFilesInTree = 200 // FileTree is a UI components that displays a file-system tree view in the terminal. type FileTree struct { - repos map[string]*dirNode - size int - exceedsMax bool + repos map[string]*dirNode + size int } func NewFileTree() *FileTree { @@ -25,11 +24,6 @@ func NewFileTree() *FileTree { // UploadedFileUrl - URL to the uploaded file in Artifactory, // if UploadedFileUrl not provided, the file name will be displayed without a link. func (ft *FileTree) AddFile(path, uploadedFileUrl string) { - if ft.size >= maxFilesInTree { - log.Info("Exceeded maximum number of files in tree") - ft.exceedsMax = true - return - } splitPath := strings.Split(path, "/") if _, exist := ft.repos[splitPath[0]]; !exist { ft.repos[splitPath[0]] = &dirNode{name: splitPath[0], prefix: "š¦ ", subDirNodes: map[string]*dirNode{}, fileNames: map[string]string{}} @@ -39,11 +33,16 @@ func (ft *FileTree) AddFile(path, uploadedFileUrl string) { } } +func (ft *FileTree) IsTreeExceedsMax() bool { + if ft.size >= maxFilesInTree { + log.Debug(fmt.Sprintf("Exceeded maximum number (%d) of files in files tree.", maxFilesInTree)) + return true + } + return false +} + // Returns a string representation of the tree. If the number of files exceeded the maximum, an empty string will be returned. func (ft *FileTree) String() string { - if ft.exceedsMax { - return "" - } treeStr := "" for _, repo := range ft.repos { treeStr += strings.Join(repo.strings(), "\n") + "\n\n" diff --git a/artifactory/utils/filetree_test.go b/artifactory/utils/filetree_test.go index eac646451..2a0e9dc8b 100644 --- a/artifactory/utils/filetree_test.go +++ b/artifactory/utils/filetree_test.go @@ -19,10 +19,8 @@ func TestFileTree(t *testing.T) { result, excpected := fileTree.String(), "š¦ repoName\nāāā š path\n āāā š to\n āāā š first\n āāā š artifact\n\n" assert.Equal(t, excpected, result) - // If maxFileInTree has exceeded, Check String() returns an empty string - fileTree.AddFile("repoName/path/to/second/artifact", "") - result, excpected = fileTree.String(), "" - assert.Equal(t, excpected, result) + // If maxFileInTree has exceeded + assert.True(t, fileTree.IsTreeExceedsMax()) } func TestFileTreeSort(t *testing.T) { diff --git a/artifactory/utils/repositoryutils.go b/artifactory/utils/repositoryutils.go index db8a46e69..40acbb86d 100644 --- a/artifactory/utils/repositoryutils.go +++ b/artifactory/utils/repositoryutils.go @@ -6,8 +6,6 @@ import ( "path" "strings" - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-client-go/artifactory" "github.com/jfrog/jfrog-client-go/artifactory/services" clientUtils "github.com/jfrog/jfrog-client-go/artifactory/services/utils" @@ -57,26 +55,6 @@ var blacklistedRepositories = []string{ "jfrog-usage-logs", "jfrog-billing-logs", "jfrog-logs", "artifactory-pipe-info", "auto-trashcan", "jfrog-support-bundle", "_intransit", "artifactory-edge-uploads", } -// GetRepositories returns the names of local, remote, virtual or federated repositories filtered by their type. -// artDetails - Artifactory server details -// repoTypes - Repository types to filter. If empty - return all repository types. -func GetRepositories(artDetails *config.ServerDetails, repoTypes ...RepoType) ([]string, error) { - sm, err := CreateServiceManager(artDetails, 3, 0, false) - if err != nil { - return nil, err - } - repos := []string{} - for _, repoType := range repoTypes { - filteredRepos, err := GetFilteredRepositoriesByNameAndType(sm, nil, nil, repoType) - if err != nil { - return repos, err - } - repos = append(repos, filteredRepos...) - } - - return repos, nil -} - // Since we can't search dependencies in a remote repository, we will turn the search to the repository's cache. // Local/Virtual repository name will be returned as is. func GetRepoNameForDependenciesSearch(repoName string, serviceManager artifactory.ArtifactoryServicesManager) (string, error) { @@ -99,44 +77,27 @@ func IsRemoteRepo(repoName string, serviceManager artifactory.ArtifactoryService return repoDetails.GetRepoType() == "remote", nil } -// GetFilteredRepositoriesByName returns the names of local, remote, virtual and federated repositories filtered by their names. -// includePatterns - patterns of repository names (can contain wildcards) to include in the results. A repository's name -// must match at least one of these patterns in order to be included in the results. If includePatterns' length is zero, -// all repositories are included. -// excludePatterns - patterns of repository names (can contain wildcards) to exclude from the results. A repository's name -// must NOT match any of these patterns in order to be included in the results. -func GetFilteredRepositoriesByName(servicesManager artifactory.ArtifactoryServicesManager, includePatterns, excludePatterns []string) ([]string, error) { - repoDetailsList, err := servicesManager.GetAllRepositories() - if err != nil { - return nil, err - } - - return getFilteredRepositories(repoDetailsList, includePatterns, excludePatterns) -} - -// GetFilteredRepositoriesByNameAndType returns the names of local, remote, virtual and federated repositories filtered by their names and type. -// includePatterns - patterns of repository names (can contain wildcards) to include in the results. A repository's name +// GetFilteredRepositoriesWithFilterParams returns the names of local, remote, virtual, and federated repositories filtered by their names and type. +// servicesManager - The Artifactory services manager used to interact with the Artifactory server. +// includePatterns - Patterns of repository names (can contain wildcards) to include in the results. A repository's name // must match at least one of these patterns in order to be included in the results. If includePatterns' length is zero, // all repositories are included. -// excludePatterns - patterns of repository names (can contain wildcards) to exclude from the results. A repository's name +// excludePatterns - Patterns of repository names (can contain wildcards) to exclude from the results. A repository's name // must NOT match any of these patterns in order to be included in the results. -// repoType - only repositories of this type will be returned. -func GetFilteredRepositoriesByNameAndType(servicesManager artifactory.ArtifactoryServicesManager, includePatterns, excludePatterns []string, repoType RepoType) ([]string, error) { - repoDetailsList, err := servicesManager.GetAllRepositoriesFiltered(services.RepositoriesFilterParams{RepoType: repoType.String()}) +// filterParams - Parameters to filter the repositories by their type. +// Returns a slice of repository names that match the given patterns and type, or an error if the operation fails. +func GetFilteredRepositoriesWithFilterParams(servicesManager artifactory.ArtifactoryServicesManager, includePatterns, excludePatterns []string, filterParams services.RepositoriesFilterParams) ([]string, error) { + repoDetailsList, err := servicesManager.GetAllRepositoriesFiltered(filterParams) if err != nil { return nil, err } - return getFilteredRepositories(repoDetailsList, includePatterns, excludePatterns) -} - -func getFilteredRepositories(repoDetailsList *[]services.RepositoryDetails, includePatterns, excludePatterns []string) ([]string, error) { - var repoKeys []string - for _, repoDetails := range *repoDetailsList { - repoKeys = append(repoKeys, repoDetails.Key) + repoKeys := make([]string, len(*repoDetailsList)) + for i, repoDetails := range *repoDetailsList { + repoKeys[i] = repoDetails.Key } - return filterRepositoryNames(&repoKeys, includePatterns, excludePatterns) + return filterRepositoryNames(repoKeys, includePatterns, excludePatterns) } // GetFilteredBuildInfoRepositories returns the names of all build-info repositories filtered by their names. @@ -147,26 +108,27 @@ func getFilteredRepositories(repoDetailsList *[]services.RepositoryDetails, incl // excludePatterns - patterns of repository names (can contain wildcards) to exclude from the results. A repository's name // must NOT match any of these patterns in order to be included in the results. func GetFilteredBuildInfoRepositories(storageInfo *clientUtils.StorageInfo, includePatterns, excludePatterns []string) ([]string, error) { - var repoKeys []string + repoKeys := make([]string, 0, len(storageInfo.RepositoriesSummaryList)) + for _, repoSummary := range storageInfo.RepositoriesSummaryList { if strings.ToLower(repoSummary.PackageType) == buildInfoPackageType { repoKeys = append(repoKeys, repoSummary.RepoKey) } } - return filterRepositoryNames(&repoKeys, includePatterns, excludePatterns) + return filterRepositoryNames(repoKeys, includePatterns, excludePatterns) } // Filter repositories by name and return a list of repository names // repos - The repository keys to filter // includePatterns - Repositories inclusion wildcard pattern // excludePatterns - Repositories exclusion wildcard pattern -func filterRepositoryNames(repoKeys *[]string, includePatterns, excludePatterns []string) ([]string, error) { +func filterRepositoryNames(repoKeys []string, includePatterns, excludePatterns []string) ([]string, error) { includedRepos := datastructures.MakeSet[string]() - includeExcludeFilter := &IncludeExcludeFilter{ + includeExcludeFilter := IncludeExcludeFilter{ IncludePatterns: includePatterns, ExcludePatterns: excludePatterns, } - for _, repoKey := range *repoKeys { + for _, repoKey := range repoKeys { repoIncluded, err := includeExcludeFilter.ShouldIncludeRepository(repoKey) if err != nil { return nil, err diff --git a/artifactory/utils/repositoryutils_test.go b/artifactory/utils/repositoryutils_test.go index a601b8012..698892d7b 100644 --- a/artifactory/utils/repositoryutils_test.go +++ b/artifactory/utils/repositoryutils_test.go @@ -26,7 +26,7 @@ func TestFilterRepositoryNames(t *testing.T) { "jfrog-npm-local", "jfrog-generic-remote", } - actualRepoNames, err := filterRepositoryNames(&repos, includePatterns, excludePatterns) + actualRepoNames, err := filterRepositoryNames(repos, includePatterns, excludePatterns) assert.NoError(t, err) assert.ElementsMatch(t, expectedRepoNames, actualRepoNames) } diff --git a/common/commands/config.go b/common/commands/config.go index d771fc865..d542593d0 100644 --- a/common/commands/config.go +++ b/common/commands/config.go @@ -36,7 +36,7 @@ type AuthenticationMethod string const ( AccessToken AuthenticationMethod = "Access Token" - BasicAuth AuthenticationMethod = "Username and Password / API Key" + BasicAuth AuthenticationMethod = "Username and Password / Reference token" MTLS AuthenticationMethod = "Mutual TLS" WebLogin AuthenticationMethod = "Web Login" ) @@ -375,10 +375,10 @@ func (cc *ConfigCommand) promptAuthMethods() (selectedMethod AuthenticationMetho var selected string authMethods := []AuthenticationMethod{ - BasicAuth, AccessToken, - MTLS, WebLogin, + BasicAuth, + MTLS, } var selectableItems []ioutils.PromptItem for _, curMethod := range authMethods { @@ -820,7 +820,7 @@ func assertSingleAuthMethod(details *config.ServerDetails) error { details.AccessToken != "" && details.ArtifactoryRefreshToken == "", details.SshKeyPath != ""} if coreutils.SumTrueValues(authMethods) > 1 { - return errorutils.CheckErrorf("Only one authentication method is allowed: Username + Password/API key, RSA Token (SSH) or Access Token") + return errorutils.CheckErrorf("Only one authentication method is allowed: Username + Password/Reference Token, RSA Token (SSH) or Access Token") } return nil } diff --git a/common/commands/configfile.go b/common/commands/configfile.go index 450e71895..f0a7e1ca0 100644 --- a/common/commands/configfile.go +++ b/common/commands/configfile.go @@ -1,6 +1,8 @@ package commands import ( + "fmt" + "github.com/jfrog/jfrog-client-go/artifactory/services" "os" "path/filepath" "strconv" @@ -134,10 +136,10 @@ func createBuildConfig(global bool, confType project.ProjectType, configFile *Co } // Populate, validate and write the config file configFilePath := filepath.Join(projectDir, confType.String()+".yaml") - if err := configFile.VerifyConfigFile(configFilePath); err != nil { + if err = configFile.VerifyConfigFile(configFilePath); err != nil { return err } - if err := handleInteractiveConfigCreation(configFile, confType); err != nil { + if err = handleInteractiveConfigCreation(configFile, confType); err != nil { return err } if err = configFile.validateConfig(); err != nil { @@ -649,7 +651,19 @@ func getRepositories(serverId string, repoTypes ...utils.RepoType) ([]string, er return nil, err } - return utils.GetRepositories(artDetails, repoTypes...) + sm, err := utils.CreateServiceManager(artDetails, 3, 0, false) + if err != nil { + return nil, err + } + repos := []string{} + for _, repoType := range repoTypes { + filteredRepos, err := utils.GetFilteredRepositoriesWithFilterParams(sm, nil, nil, services.RepositoriesFilterParams{RepoType: repoType.String()}) + if err != nil { + return nil, fmt.Errorf("failed getting %s repositories list: %w", repoType.String(), err) + } + repos = append(repos, filteredRepos...) + } + return repos, nil } func defaultIfNotSet(c *cli.Context, flagName string, defaultValue string) string { diff --git a/go.mod b/go.mod index 7a88aed6f..a21d6f119 100644 --- a/go.mod +++ b/go.mod @@ -12,9 +12,9 @@ require ( github.com/google/uuid v1.6.0 github.com/gookit/color v1.5.4 github.com/jedib0t/go-pretty/v6 v6.5.9 - github.com/jfrog/build-info-go v1.10.2 + github.com/jfrog/build-info-go v1.10.3 github.com/jfrog/gofrog v1.7.6 - github.com/jfrog/jfrog-client-go v1.47.1 + github.com/jfrog/jfrog-client-go v1.47.2 github.com/magiconair/properties v1.8.7 github.com/manifoldco/promptui v0.9.0 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c @@ -98,6 +98,6 @@ require ( // replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240918081224-1c584cc334c7 -// replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20240918150101-ad5b10435a12 +// replace github.com/jfrog/build-info-go => github.com/galusben/build-info-go v0.0.0-20240930113238-ac3b31030284 // replace github.com/jfrog/gofrog => github.com/jfrog/gofrog v1.3.3-0.20231223133729-ef57bd08cedc diff --git a/go.sum b/go.sum index 05bb6f265..f923c8da7 100644 --- a/go.sum +++ b/go.sum @@ -92,12 +92,12 @@ github.com/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+ github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5eI= github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw= -github.com/jfrog/build-info-go v1.10.2 h1:RCCBsahRNYOm3W7Z9tAL/ixBLzrOzm4mTgI2N6jvqsw= -github.com/jfrog/build-info-go v1.10.2/go.mod h1:JcISnovFXKx3wWf3p1fcMmlPdt6adxScXvoJN4WXqIE= +github.com/jfrog/build-info-go v1.10.3 h1:9nqBdZD6xkuxiOvxg+idZ79QLFWQNuucvKkl8Xb42kw= +github.com/jfrog/build-info-go v1.10.3/go.mod h1:JcISnovFXKx3wWf3p1fcMmlPdt6adxScXvoJN4WXqIE= github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s= github.com/jfrog/gofrog v1.7.6/go.mod h1:ntr1txqNOZtHplmaNd7rS4f8jpA5Apx8em70oYEe7+4= -github.com/jfrog/jfrog-client-go v1.47.1 h1:VT2v28/usTSP56+i3MC3fgRvZoh6vjRgQgs8xTk+sYU= -github.com/jfrog/jfrog-client-go v1.47.1/go.mod h1:7M/vgei7VGcLjUxwQ/3r9pH3lvDHlt6Q+Gw+YMis/mc= +github.com/jfrog/jfrog-client-go v1.47.2 h1:Lu+2n4EU+MzNfotV1VOvF/ZQIWsQJg11Z4YSVhumFy0= +github.com/jfrog/jfrog-client-go v1.47.2/go.mod h1:fx2fq5XwZ7e2pzpBB9pXsP8+ZdKLB8g+A6fjGU6F2XI= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= diff --git a/utils/ioutils/ioutils.go b/utils/ioutils/ioutils.go index c624eb5a7..c410c4d25 100644 --- a/utils/ioutils/ioutils.go +++ b/utils/ioutils/ioutils.go @@ -40,7 +40,7 @@ func ReadCredentialsFromConsole(details, savedDetails coreutils.Credentials, dis } func ScanJFrogPasswordFromConsole() (string, error) { - return ScanPasswordFromConsole("JFrog password or API key: ") + return ScanPasswordFromConsole("JFrog password or Reference Token: ") } func ScanPasswordFromConsole(message string) (string, error) { diff --git a/utils/mvn/utils.go b/utils/mvn/utils.go index 89640d45c..876344e17 100644 --- a/utils/mvn/utils.go +++ b/utils/mvn/utils.go @@ -14,6 +14,7 @@ import ( "github.com/jfrog/jfrog-cli-core/v2/utils/config" "github.com/jfrog/jfrog-cli-core/v2/utils/dependencies" "github.com/jfrog/jfrog-client-go/utils/errorutils" + "github.com/jfrog/jfrog-client-go/utils/io/fileutils" "github.com/spf13/viper" ) @@ -102,6 +103,13 @@ func RunMvn(mu *MvnUtils) error { if v, ok := props["buildInfoConfig.artifactoryResolutionEnabled"]; ok { mvnOpts = append(mvnOpts, "-DbuildInfoConfig.artifactoryResolutionEnabled="+v) } + projectRoot, exists, err := fileutils.FindUpstream(".mvn", fileutils.Dir) + if err != nil { + return errorutils.CheckError(err) + } + if !exists { + projectRoot = "" + } dependencyLocalPath, err := getMavenDependencyLocalPath() if err != nil { return err @@ -114,6 +122,7 @@ func RunMvn(mu *MvnUtils) error { useWrapper). SetOutputWriter(mu.outputWriter) mavenModule.SetMavenOpts(mvnOpts...) + mavenModule.SetRootProjectDir(projectRoot) if err = coreutils.ConvertExitCodeError(mavenModule.CalcDependencies()); err != nil { return err }