diff --git a/artifactory/cli.go b/artifactory/cli.go index 36187bdb9..db13c4cbf 100644 --- a/artifactory/cli.go +++ b/artifactory/cli.go @@ -1173,6 +1173,7 @@ func transferFilesCmd(c *cli.Context) error { includeReposPatterns, excludeReposPatterns := getTransferIncludeExcludeRepos(c) newTransferFilesCmd.SetIncludeReposPatterns(includeReposPatterns) newTransferFilesCmd.SetExcludeReposPatterns(excludeReposPatterns) + newTransferFilesCmd.SetIncludeFilesPatterns(getIncludeFilesPatterns(c)) newTransferFilesCmd.SetIgnoreState(c.Bool(cliutils.IgnoreState)) newTransferFilesCmd.SetProxyKey(c.String(cliutils.ProxyKey)) return newTransferFilesCmd.Run() @@ -1189,6 +1190,14 @@ func getTransferIncludeExcludeRepos(c *cli.Context) (includeReposPatterns, exclu return } +func getIncludeFilesPatterns(c *cli.Context) []string { + const patternSeparator = ";" + if c.IsSet(cliutils.IncludeFiles) { + return strings.Split(c.String(cliutils.IncludeFiles), patternSeparator) + } + return nil +} + func getTransferIncludeExcludeProjects(c *cli.Context) (includeProjectsPatterns, excludeProjectsPatterns []string) { const patternSeparator = ";" if c.IsSet(cliutils.IncludeProjects) { diff --git a/artifactory/cli_test.go b/artifactory/cli_test.go index 539c38132..af6caae8b 100644 --- a/artifactory/cli_test.go +++ b/artifactory/cli_test.go @@ -2,10 +2,11 @@ package artifactory import ( "bytes" - "github.com/jfrog/jfrog-cli-artifactory/cliutils/flagkit" "path/filepath" "testing" + "github.com/jfrog/jfrog-cli-artifactory/cliutils/flagkit" + commonCliUtils "github.com/jfrog/jfrog-cli-core/v2/common/cliutils" "github.com/jfrog/jfrog-cli-core/v2/common/spec" "github.com/jfrog/jfrog-cli/utils/cliutils" @@ -154,3 +155,46 @@ func TestCreateUploadConfiguration(t *testing.T) { }) } } + +// Test cases for getIncludeFilesPatterns +var getIncludeFilesPatternsTestCases = []struct { + name string + flags []string + expectedPatterns []string +}{ + { + name: "no flag set", + flags: []string{}, + expectedPatterns: nil, + }, + { + name: "single pattern", + flags: []string{cliutils.IncludeFiles + "=org/company/*"}, + expectedPatterns: []string{"org/company/*"}, + }, + { + name: "multiple patterns", + flags: []string{cliutils.IncludeFiles + "=org/company/*;com/example/*"}, + expectedPatterns: []string{"org/company/*", "com/example/*"}, + }, + { + name: "three patterns", + flags: []string{cliutils.IncludeFiles + "=path1/*;path2/*;path3/*"}, + expectedPatterns: []string{"path1/*", "path2/*", "path3/*"}, + }, + { + name: "pattern with deep nesting", + flags: []string{cliutils.IncludeFiles + "=a/b/c/d/e/*"}, + expectedPatterns: []string{"a/b/c/d/e/*"}, + }, +} + +func TestGetIncludeFilesPatterns(t *testing.T) { + for _, testCase := range getIncludeFilesPatternsTestCases { + t.Run(testCase.name, func(t *testing.T) { + context, _ := tests.CreateContext(t, testCase.flags, []string{}) + patterns := getIncludeFilesPatterns(context) + assert.Equal(t, testCase.expectedPatterns, patterns) + }) + } +} diff --git a/artifactory_test.go b/artifactory_test.go index 33104cb8c..5cb271e04 100644 --- a/artifactory_test.go +++ b/artifactory_test.go @@ -276,13 +276,13 @@ func TestReleaseBundleImportOnPrem(t *testing.T) { func TestReleaseBundleV2Download(t *testing.T) { buildNumber := "5" + initArtifactoryTest(t, "") + initLifecycleTest(t, signingKeyOptionalArtifactoryMinVersion) defer func() { deleteReceivedReleaseBundle(t, deleteReleaseBundleV2ApiUrl, tests.LcRbName1, buildNumber) inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, tests.RtBuildName1, artHttpDetails) cleanArtifactoryTest() }() - initArtifactoryTest(t, "") - initLifecycleTest(t, signingKeyOptionalArtifactoryMinVersion) runRt(t, "upload", "testdata/a/a1.in", tests.RtRepo1, "--build-name="+tests.RtBuildName1, "--build-number="+buildNumber) runRt(t, "build-publish", tests.RtBuildName1, buildNumber) diff --git a/go.mod b/go.mod index 3c127d6e8..c6de3ea88 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/jfrog/gofrog v1.7.6 github.com/jfrog/jfrog-cli-application v1.0.2-0.20251210075951-519050602a7f github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20251218044417-5113b260e416 - github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251210085744-f8481d179ac5 + github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251219102726-2cbe70d57403 github.com/jfrog/jfrog-cli-evidence v0.8.3-0.20251204144808-73fa744851c0 github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20251205121610-171eb9b0000e github.com/jfrog/jfrog-cli-security v1.24.1 diff --git a/go.sum b/go.sum index 49469e87f..01551316c 100644 --- a/go.sum +++ b/go.sum @@ -1220,6 +1220,8 @@ github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20251218044417-5113b260e416 h1:b github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20251218044417-5113b260e416/go.mod h1:7cCaRhXorlbyXZgiW5bplCExFxlnROaG21K12d8inpQ= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251210085744-f8481d179ac5 h1:GYE67ubwl+ZRw3CcXFUi49EwwQp6k+qS8sX0QuHDHO8= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251210085744-f8481d179ac5/go.mod h1:BMoGi2rG0udCCeaghqlNgiW3fTmT+TNnfTnBoWFYgcg= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251219102726-2cbe70d57403 h1:Hnw9eOCdybMBAh1pUt9FCs74CTDOUh0M79ZCQ3VKPc4= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251219102726-2cbe70d57403/go.mod h1:BMoGi2rG0udCCeaghqlNgiW3fTmT+TNnfTnBoWFYgcg= github.com/jfrog/jfrog-cli-evidence v0.8.3-0.20251204144808-73fa744851c0 h1:8S1vE1PeVtrzWkKL0N39cX6XLLNV0It+f6xjRKjw7Ug= github.com/jfrog/jfrog-cli-evidence v0.8.3-0.20251204144808-73fa744851c0/go.mod h1:Ijx7tkTp6uDxgmQW+zQKLNztMrz6dcQAoVNXHL7spsU= github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20251205121610-171eb9b0000e h1:0BDeb5lD8qgQMOZJ08E35jUMTlt2Hb0K7Wu0SqO6MrI= diff --git a/utils/cliutils/commandsflags.go b/utils/cliutils/commandsflags.go index 68ffdd03c..c56741c43 100644 --- a/utils/cliutils/commandsflags.go +++ b/utils/cliutils/commandsflags.go @@ -564,6 +564,7 @@ const ( ExcludeRepos = "exclude-repos" IncludeProjects = "include-projects" ExcludeProjects = "exclude-projects" + IncludeFiles = "include-files" // *** JFrog Pipelines Commands' flags *** // Base flags @@ -1607,6 +1608,10 @@ var flagsMap = map[string]cli.Flag{ Name: ExcludeProjects, Usage: "[Optional] List of semicolon-separated(;) JFrog Projects to exclude from the transfer. You can use wildcards to specify patterns for the project keys.` `", }, + IncludeFiles: cli.StringFlag{ + Name: IncludeFiles, + Usage: "[Optional] List of semicolon-separated(;) path patterns to include in the transfer. Files will be filtered based on their directory path. Pattern examples: 'folder/subfolder/*', 'org/company/*'.` `", + }, IgnoreState: cli.BoolFlag{ Name: IgnoreState, Usage: "[Default: false] Set to true to ignore the saved state from previous transfer-files operations.` `", @@ -2035,7 +2040,7 @@ var commandFlags = map[string][]string{ url, user, password, accessToken, sshPassphrase, sshKeyPath, serverId, deleteQuiet, }, TransferFiles: { - Filestore, IncludeRepos, ExcludeRepos, IgnoreState, ProxyKey, transferFilesStatus, Stop, PreChecks, + Filestore, IncludeRepos, ExcludeRepos, IncludeFiles, IgnoreState, ProxyKey, transferFilesStatus, Stop, PreChecks, }, TransferInstall: { installPluginVersion, InstallPluginSrcDir, InstallPluginHomeDir,