From dd83b0aa9ba1434c2126070bb635aa0469a5815b Mon Sep 17 00:00:00 2001 From: tamirhadad Date: Sun, 14 May 2017 18:09:26 +0300 Subject: [PATCH] Leading directories unwantedly preserved with copy/move --- artifactory/cli.go | 2 +- artifactory/commands/delete.go | 71 ++------- artifactory/commands/delete_test.go | 68 --------- artifactory/commands/upload_test.go | 12 +- artifactory/utils/aqlquerybuilder.go | 38 +---- artifactory/utils/aqlquerybuilder_test.go | 10 +- artifactory/utils/aqlsearchutil.go | 41 +++++ artifactory/utils/aqlsearchutil_test.go | 61 ++++++++ artifactory/utils/moveutils.go | 6 +- jfrog/artifactory_test.go | 141 +++++++++++++++++- testsdata/specs/common/copy_items_spec.json | 10 ++ .../specs/common/move_copy_delete_spec.json | 8 +- testsdata/specs/common/prepare_copy.json | 4 +- utils/tests/artifactoryconsts.go | 124 ++++++++------- 14 files changed, 352 insertions(+), 244 deletions(-) delete mode 100644 artifactory/commands/delete_test.go create mode 100644 testsdata/specs/common/copy_items_spec.json diff --git a/artifactory/cli.go b/artifactory/cli.go index c14e2f94a..03ae49703 100644 --- a/artifactory/cli.go +++ b/artifactory/cli.go @@ -966,7 +966,7 @@ func createDefaultMoveSpec(c *cli.Context) *utils.SpecFiles { recursive := cliutils.GetBoolFlagValue(c, "recursive", true) flat := cliutils.GetBoolFlagValue(c, "flat", false) - return utils.CreateSpec(pattern, target, props, build, recursive, flat, false, false) + return utils.CreateSpec(pattern, target, props, build, recursive, flat, false, true) } func getMoveSpec(c *cli.Context) (searchSpec *utils.SpecFiles, err error) { diff --git a/artifactory/commands/delete.go b/artifactory/commands/delete.go index a131a6c93..b58568aeb 100644 --- a/artifactory/commands/delete.go +++ b/artifactory/commands/delete.go @@ -6,7 +6,6 @@ import ( "github.com/jfrogdev/jfrog-cli-go/utils/config" "github.com/jfrogdev/jfrog-cli-go/utils/cliutils" "github.com/jfrogdev/jfrog-cli-go/utils/cliutils/log" - "strings" "errors" ) @@ -36,9 +35,10 @@ func GetPathsToDelete(deleteSpec *utils.SpecFiles, flags *DeleteFlags) ([]utils. func getPathsToDeleteInternal(deleteSpec *utils.SpecFiles, flags *DeleteFlags) (resultItems []utils.AqlSearchResultItem, err error) { log.Info("Searching artifacts...") for i := 0; i < len(deleteSpec.Files); i++ { + currentSpec := deleteSpec.Get(i) // Search paths using AQL. - if deleteSpec.Get(i).GetSpecType() == utils.AQL { - if resultItemsTemp, e := utils.AqlSearchBySpec(deleteSpec.Get(i), flags); e == nil { + if currentSpec.GetSpecType() == utils.AQL { + if resultItemsTemp, e := utils.AqlSearchBySpec(currentSpec, flags); e == nil { resultItems = append(resultItems, resultItemsTemp...) continue } else { @@ -47,36 +47,23 @@ func getPathsToDeleteInternal(deleteSpec *utils.SpecFiles, flags *DeleteFlags) ( } } // Simple directory delete, no need to search in Artifactory. - if simpleDir, e := isSimpleDirectoryDelete(deleteSpec.Get(i)); simpleDir && e == nil { - simplePathItem := utils.AqlSearchResultItem{Path:deleteSpec.Get(i).Pattern} + if simpleDir, e := isSimpleDirectoryDelete(currentSpec); simpleDir && e == nil { + simplePathItem := utils.AqlSearchResultItem{Path:currentSpec.Pattern} resultItems = append(resultItems, []utils.AqlSearchResultItem{simplePathItem}...) continue } else if e != nil { err = e return } - // Directory with wildcard pattern, searching with special AQL query. - if directoryDelete, e := isDirectoryDelete(deleteSpec.Get(i)); directoryDelete && e == nil { - query := utils.BuildAqlFolderSearchQuery(deleteSpec.Get(i).Pattern, utils.GetDefaultQueryReturnFields()) - tempResultItems, e := utils.AqlSearch(query, flags) - if e != nil { - err = e - return - } - paths := reduceDirResult(tempResultItems) - resultItems = append(resultItems, paths...) - continue - } else if e != nil { - err = e - return - } - // All other use cases, pattern with/without wildcard files. - tempResultItems, e := utils.AqlSearchDefaultReturnFields(deleteSpec.Get(i), flags) + + currentSpec.IncludeDirs = "true" + tempResultItems, e := utils.AqlSearchDefaultReturnFields(currentSpec, flags) if e != nil { err = e return } - resultItems = append(resultItems, tempResultItems...) + paths := utils.ReduceDirResult(tempResultItems) + resultItems = append(resultItems, paths...) } utils.LogSearchResults(len(resultItems)) return @@ -95,44 +82,6 @@ func isSimpleDirectoryDelete(deleteFile *utils.File) (bool, error) { return utils.IsSimpleDirectoryPath(deleteFile.Pattern) && isRecursive && deleteFile.Props == "", nil } -// The diffrence between isSimpleDirectoryDelete to isDirectoryDelete is: -// isDirectoryDelete returns true when the deleteFile path contains wildcatds. -func isDirectoryDelete(deleteFile *utils.File) (bool, error) { - isRecursive, err := cliutils.StringToBool(deleteFile.Recursive, true) - if err != nil { - return false, err - } - return utils.IsDirectoryPath(deleteFile.Pattern) && isRecursive && deleteFile.Props == "", nil -} - -// Remove unnecessary paths. -// For example if we have two paths for delete a/b/c/ and a/b/ -// it's enough to delete only a/b/ -func reduceDirResult(foldersToDelete []utils.AqlSearchResultItem) []utils.AqlSearchResultItem { - paths := make(map[string]utils.AqlSearchResultItem) - for _, file := range foldersToDelete { - if file.Name == "." { - continue - } - paths[file.GetFullUrl()] = file - } - - for k := range paths { - for k2 := range paths { - if k != k2 && strings.HasPrefix(k, k2) { - delete(paths, k); - continue - } - } - } - var result []utils.AqlSearchResultItem - for _, v := range paths { - v.Name += "/" - result = append(result, v) - } - return result -} - func DeleteFiles(resultItems []utils.AqlSearchResultItem, flags *DeleteFlags) error { if err := utils.PreCommandSetup(flags); err != nil { return err diff --git a/artifactory/commands/delete_test.go b/artifactory/commands/delete_test.go deleted file mode 100644 index 7e7e56ec4..000000000 --- a/artifactory/commands/delete_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package commands - -import ( - "testing" - "github.com/jfrogdev/jfrog-cli-go/artifactory/utils" - "strconv" -) - -func TestReduceDirResult(t *testing.T) { - paths := []utils.AqlSearchResultItem{} - expected := []utils.AqlSearchResultItem{} - - paths = append(paths, utils.AqlSearchResultItem{Repo:"repo1", Path:"b", Name:"c"}) - expected = append(expected, utils.AqlSearchResultItem{Repo:"repo1", Path:"b", Name:"c/"}) - assertPackageFiles(expected, reduceDirResult(paths), t) - - paths = append(paths, utils.AqlSearchResultItem{Repo:"repo1", Path:"br", Name:"c"}) - expected = append(expected, utils.AqlSearchResultItem{Repo:"repo1", Path:"br", Name:"c/"}) - assertPackageFiles(expected, reduceDirResult(paths), t) - - paths = append(paths, utils.AqlSearchResultItem{Repo:"repo1", Path:"br/c/dont/care", Name:"somename"}) - assertPackageFiles(expected, reduceDirResult(paths), t) - - paths = append(paths, utils.AqlSearchResultItem{Repo:"repo1", Path:"bl", Name:"c1"}) - expected = append(expected, utils.AqlSearchResultItem{Repo:"repo1", Path:"bl", Name:"c1/"}) - assertPackageFiles(expected, reduceDirResult(paths), t) - - paths = append(paths, utils.AqlSearchResultItem{Repo:"repo1", Path:"bl/c1/you/dont/care", Name:"somename"}) - assertPackageFiles(expected, reduceDirResult(paths), t) - - paths = append(paths, utils.AqlSearchResultItem{Repo:"repo1", Path:"bl/c1/i/dont/care", Name:"somename"}) - assertPackageFiles(expected, reduceDirResult(paths), t) - - paths = append(paths, utils.AqlSearchResultItem{Repo:"repo1", Path:"b", Name:"."}) - assertPackageFiles(expected, reduceDirResult(paths), t) - - paths = append(paths, utils.AqlSearchResultItem{Repo:"repo2", Path:"bl", Name:"c1"}) - expected = append(expected, utils.AqlSearchResultItem{Repo:"repo2", Path:"bl", Name:"c1/"}) - assertPackageFiles(expected, reduceDirResult(paths), t) -} - - -func assertPackageFiles(expected, actual []utils.AqlSearchResultItem, t *testing.T) { - if len(actual) != len(expected) { - t.Error("Expected: " + strconv.Itoa(len(expected)) + ", Got: " + strconv.Itoa(len(actual)) + " files.") - } - - expectedMap := make(map[string]utils.AqlSearchResultItem) - for _, v := range expected { - expectedMap[v.GetFullUrl()] = v - } - - actualMap := make(map[string]utils.AqlSearchResultItem) - for _, v := range actual { - actualMap[v.GetFullUrl()] = v - } - - for _, v := range actual { - if _, ok := expectedMap[v.GetFullUrl()]; !ok { - t.Error("Unexpected path:", v.GetFullUrl()) - } - } - for _, v := range expected { - if _, ok := actualMap[v.GetFullUrl()]; !ok { - t.Error("Path not found:", v.GetFullUrl()) - } - } -} \ No newline at end of file diff --git a/artifactory/commands/upload_test.go b/artifactory/commands/upload_test.go index 12285ed90..4c01d332e 100644 --- a/artifactory/commands/upload_test.go +++ b/artifactory/commands/upload_test.go @@ -10,15 +10,15 @@ import ( func TestSingleFileUpload(t *testing.T) { flags := getUploadFlags() - spec := utils.CreateSpec("testdata/a.txt", "repo-local", "", "", false, true, false) + spec := utils.CreateSpec("testdata/a.txt", "repo-local", "", "", false, true, false, false) uploaded1, _, err := Upload(spec, flags) checkUploaded(t, uploaded1, err, 1) - spec = utils.CreateSpec("testdata/aa.txt", "repo-local", "", "", false, true, false) + spec = utils.CreateSpec("testdata/aa.txt", "repo-local", "", "", false, true, false, false) uploaded2, _, err := Upload(spec, flags) checkUploaded(t, uploaded2, err, 1) - spec = utils.CreateSpec("testdata/aa1*.txt", "repo-local", "", "", false, true, false) + spec = utils.CreateSpec("testdata/aa1*.txt", "repo-local", "", "", false, true, false, false) uploaded3, _, err := Upload(spec, flags) checkUploaded(t, uploaded3, err, 0) @@ -36,15 +36,15 @@ func TestPatternNonRecursiveUpload(t *testing.T) { func testPatternUpload(t *testing.T, recursive bool, flags *UploadFlags) { sep := cliutils.GetTestsFileSeperator() - spec := utils.CreateSpec("testdata" + sep + "*", "repo-local", "", "", recursive, true, false) + spec := utils.CreateSpec("testdata" + sep + "*", "repo-local", "", "", recursive, true, false, false) uploaded1, _, err := Upload(spec, flags) checkUploaded(t, uploaded1, err, 3) - spec = utils.CreateSpec("testdata" + sep + "a*", "repo-local", "", "", recursive, true, false) + spec = utils.CreateSpec("testdata" + sep + "a*", "repo-local", "", "", recursive, true, false, false) uploaded2, _, err := Upload(spec, flags) checkUploaded(t, uploaded2, err, 2) - spec = utils.CreateSpec("testdata" + sep + "b*", "repo-local", "", "", recursive, true, false) + spec = utils.CreateSpec("testdata" + sep + "b*", "repo-local", "", "", recursive, true, false, false) uploaded3, _, err := Upload(spec, flags) checkUploaded(t, uploaded3, err, 1) } diff --git a/artifactory/utils/aqlquerybuilder.go b/artifactory/utils/aqlquerybuilder.go index a3d5259eb..971990efe 100644 --- a/artifactory/utils/aqlquerybuilder.go +++ b/artifactory/utils/aqlquerybuilder.go @@ -6,26 +6,6 @@ import ( "github.com/jfrogdev/jfrog-cli-go/utils/cliutils" ) -//Returns an AQL query string to search folders in Artifactory according to the pattern and return fields provided. -func BuildAqlFolderSearchQuery(searchPattern string, aqlReturnFields []string) string { - pairs := createPathFolderPairs(searchPattern) - index := strings.Index(searchPattern, "/") - repo := searchPattern[:index] - - size := len(pairs) - json := "{\"repo\": \"" + repo + "\",\"$or\": [" - - for i := 0; i < size; i++ { - json += "{" + buildInnerQuery(pairs[i].path, pairs[i].file, "folder") + "}" - if i + 1 < size { - json += "," - } - } - - json += "]}" - return "items.find(" + json + ").include(" + buildAqlReturnFieldsString(aqlReturnFields) + ")" -} - // Returns an AQL body string to search file in Artifactory according the the specified arguments requirements. func createAqlBodyForItem(specFile *File) (string, error) { var itemType string @@ -44,6 +24,7 @@ func createAqlBodyForItem(specFile *File) (string, error) { } pairs := createPathFilePairs(searchPattern, recursive) + includeRoot := strings.LastIndex(searchPattern, "/") < 0 size := len(pairs) propsQuery, err := buildPropsQuery(specFile.Props) if err != nil { @@ -52,10 +33,10 @@ func createAqlBodyForItem(specFile *File) (string, error) { json := "{\"repo\": \"" + repo + "\"," + propsQuery + "\"$or\": [" if size == 0 { - json += "{" + buildInnerQuery(".", searchPattern, itemType) + "}" + json += "{" + buildInnerQuery(".", searchPattern, itemType, true) + "}" } else { for i := 0; i < size; i++ { - json += "{" + buildInnerQuery(pairs[i].path, pairs[i].file, itemType) + "}" + json += "{" + buildInnerQuery(pairs[i].path, pairs[i].file, itemType, includeRoot) + "}" if i+1 < size { json += "," } @@ -114,13 +95,13 @@ func buildPropsQuery(props string) (string, error) { return query, nil } -func buildInnerQuery(path, name, itemType string) string { +func buildInnerQuery(path, name, itemType string, includeRoot bool) string { itemTypeQuery := "" if itemType != "" { itemTypeQuery = ",\"type\": {\"$eq\": \"" + itemType + "\"}" } nePath := "" - if itemType == "folder" && path == "*" && name == "*" { + if !includeRoot { nePath = "\"path\": {\"$ne\": \".\"}," } @@ -198,14 +179,7 @@ func createPathFilePairs(pattern string, recursive bool) []PathFilePair { } else { path = pattern[:slashIndex] name = pattern[slashIndex+1:] - if path == "*" { - pairs = append(pairs, PathFilePair{path + "/*", name}) - if name == "*" { - return pairs - } - } else { - pairs = append(pairs, PathFilePair{path, name}) - } + pairs = append(pairs, PathFilePair{path, name}) } if !recursive { return pairs diff --git a/artifactory/utils/aqlquerybuilder_test.go b/artifactory/utils/aqlquerybuilder_test.go index 68ce1ebd3..0e4ba9444 100644 --- a/artifactory/utils/aqlquerybuilder_test.go +++ b/artifactory/utils/aqlquerybuilder_test.go @@ -17,7 +17,7 @@ func TestBuildAqlSearchQueryRecursiveSimple(t *testing.T) { func TestBuildAqlSearchQueryRecursiveWildcard(t *testing.T) { specFile := CreateSpec("repo-local2/a*b*c/dd/", "", "", "", true, true, false, false).Files[0] aqlResult, _ := createAqlBodyForItem(&specFile) - expected := "{\"repo\": \"repo-local2\",\"$or\": [{\"$and\": [{\"path\": {\"$match\": \"a*b*c/dd\"},\"name\": {\"$match\": \"*\"}}]},{\"$and\": [{\"path\": {\"$match\": \"a*b*c/dd/*\"},\"name\": {\"$match\": \"*\"}}]}]}" + expected := "{\"repo\": \"repo-local2\",\"$or\": [{\"$and\": [{\"path\": {\"$match\": \"a*b*c/dd\"},\"path\": {\"$ne\": \".\"},\"name\": {\"$match\": \"*\"}}]},{\"$and\": [{\"path\": {\"$match\": \"a*b*c/dd/*\"},\"path\": {\"$ne\": \".\"},\"name\": {\"$match\": \"*\"}}]}]}" if aqlResult != expected { t.Error("Unexpected download AQL query built. \nExpected: " + expected + " \nGot: " + aqlResult) @@ -37,7 +37,7 @@ func TestBuildAqlSearchQueryNonRecursiveSimple(t *testing.T) { func TestBuildAqlSearchQueryNonRecursiveWildcard(t *testing.T) { specFile := CreateSpec("repo-local2/a*b*c/dd/", "", "", "", false, true, false, false).Files[0] aqlResult, _ := createAqlBodyForItem(&specFile) - expected := "{\"repo\": \"repo-local2\",\"$or\": [{\"$and\": [{\"path\": {\"$match\": \"a*b*c/dd\"},\"name\": {\"$match\": \"*\"}}]}]}" + expected := "{\"repo\": \"repo-local2\",\"$or\": [{\"$and\": [{\"path\": {\"$match\": \"a*b*c/dd\"},\"path\": {\"$ne\": \".\"},\"name\": {\"$match\": \"*\"}}]}]}" if aqlResult != expected { t.Error("Unexpected download AQL query built. \nExpected: " + expected + " \nGot: " + aqlResult) @@ -59,12 +59,10 @@ func TestCreatePathFilePairs(t *testing.T) { validatePathPairs(createPathFilePairs("*/a*/*b*a*", true), pairs, "*/a*/*b*a*", t) pairs = []PathFilePair{{"*", "*"}} validatePathPairs(createPathFilePairs("*", true), pairs, "*", t) - pairs = []PathFilePair{{"*/*", "*"}} + pairs = []PathFilePair{{"*", "*"}, {"*/*", "*"}} validatePathPairs(createPathFilePairs("*/*", true), pairs, "*/*", t) - pairs = []PathFilePair{{"*/*", "a.z"}} + pairs = []PathFilePair{{"*", "a.z"}} validatePathPairs(createPathFilePairs("*/a.z", true), pairs, "*/a.z", t) - pairs = []PathFilePair{{"*/*", "*"}} - validatePathPairs(createPathFilePairs("*/*", false), pairs, "*/*", t) pairs = []PathFilePair{{".", "a"}} validatePathPairs(createPathFilePairs("a", false), pairs, "a", t) pairs = []PathFilePair{{"", "*"}} diff --git a/artifactory/utils/aqlsearchutil.go b/artifactory/utils/aqlsearchutil.go index c09509b6c..7ae7b22bc 100644 --- a/artifactory/utils/aqlsearchutil.go +++ b/artifactory/utils/aqlsearchutil.go @@ -9,6 +9,7 @@ import ( "strconv" "github.com/jfrogdev/jfrog-cli-go/utils/cliutils/log" "errors" + "sort" ) func AqlSearchDefaultReturnFields(specFile *File, flags AqlSearchFlag) ([]AqlSearchResultItem, error) { @@ -113,6 +114,9 @@ func (item AqlSearchResultItem) GetFullUrl() string { url := item.Repo url = addSeparator(url, "/", item.Path) url = addSeparator(url, "/", item.Name) + if item.Type == "folder" && !strings.HasSuffix(url,"/") { + url = url + "/" + } return url } @@ -129,4 +133,41 @@ func addSeparator(str1, separator, str2 string) string { type AqlSearchFlag interface { GetArtifactoryDetails() *config.ArtifactoryDetails +} + +// Remove unnecessary paths. +// For example if we have two paths for delete a/b/c/ and a/b/ +// it's enough to delete only a/b/ +func ReduceDirResult(searchResults []AqlSearchResultItem) []AqlSearchResultItem { + paths := make(map[string]AqlSearchResultItem) + pathsKeys := make([]string, 0, len(searchResults)) + for _, file := range searchResults { + if file.Name == "." { + continue + } + + url := file.GetFullUrl() + paths[url] = file + pathsKeys = append(pathsKeys, url) + } + sort.Strings(pathsKeys) + for _, k := range pathsKeys { + for _, k2 := range pathsKeys { + prefix := k2 + if paths[k2].Type == "folder" && !strings.HasSuffix(k2, "/") { + prefix += "/" + } + + if k != k2 && strings.HasPrefix(k, prefix) { + delete(paths, k) + continue + } + } + } + + var result []AqlSearchResultItem + for _, v := range paths { + result = append(result, v) + } + return result } \ No newline at end of file diff --git a/artifactory/utils/aqlsearchutil_test.go b/artifactory/utils/aqlsearchutil_test.go index 8715547e3..5050dc10d 100644 --- a/artifactory/utils/aqlsearchutil_test.go +++ b/artifactory/utils/aqlsearchutil_test.go @@ -2,6 +2,7 @@ package utils import ( "testing" + "strconv" ) func TestGetFullUrl(t *testing.T) { @@ -18,4 +19,64 @@ func assertUrl(repo, path, name, fullUrl string, t *testing.T) { if fullUrl != testItem.GetFullUrl() { t.Error("Unexpected URL built. Expected: `" + fullUrl + "` Got `" + testItem.GetFullUrl() + "`") } +} + +func TestReduceDirResult(t *testing.T) { + paths := []AqlSearchResultItem{} + expected := []AqlSearchResultItem{} + + paths = append(paths, AqlSearchResultItem{Repo:"repo1", Path:"b", Name:"c/"}) + expected = append(expected, AqlSearchResultItem{Repo:"repo1", Path:"b", Name:"c/"}) + assertPackageFiles(expected, ReduceDirResult(paths), t) + + paths = append(paths, AqlSearchResultItem{Repo:"repo1", Path:"br", Name:"c/"}) + expected = append(expected, AqlSearchResultItem{Repo:"repo1", Path:"br", Name:"c/"}) + assertPackageFiles(expected, ReduceDirResult(paths), t) + + paths = append(paths, AqlSearchResultItem{Repo:"repo1", Path:"br/c/dont/care", Name:"somename"}) + assertPackageFiles(expected, ReduceDirResult(paths), t) + + paths = append(paths, AqlSearchResultItem{Repo:"repo1", Path:"bl", Name:"c1/"}) + expected = append(expected, AqlSearchResultItem{Repo:"repo1", Path:"bl", Name:"c1/"}) + assertPackageFiles(expected, ReduceDirResult(paths), t) + + paths = append(paths, AqlSearchResultItem{Repo:"repo1", Path:"bl/c1/you/dont/care", Name:"somename"}) + assertPackageFiles(expected, ReduceDirResult(paths), t) + + paths = append(paths, AqlSearchResultItem{Repo:"repo1", Path:"bl/c1/i/dont/care", Name:"somename"}) + assertPackageFiles(expected, ReduceDirResult(paths), t) + + paths = append(paths, AqlSearchResultItem{Repo:"repo1", Path:"b", Name:"."}) + assertPackageFiles(expected, ReduceDirResult(paths), t) + + paths = append(paths, AqlSearchResultItem{Repo:"repo2", Path:"bl", Name:"c1"}) + expected = append(expected, AqlSearchResultItem{Repo:"repo2", Path:"bl", Name:"c1"}) + assertPackageFiles(expected, ReduceDirResult(paths), t) +} + +func assertPackageFiles(expected, actual []AqlSearchResultItem, t *testing.T) { + if len(actual) != len(expected) { + t.Error("Expected: " + strconv.Itoa(len(expected)) + ", Got: " + strconv.Itoa(len(actual)) + " files.") + } + + expectedMap := make(map[string]AqlSearchResultItem) + for _, v := range expected { + expectedMap[v.GetFullUrl()] = v + } + + actualMap := make(map[string]AqlSearchResultItem) + for _, v := range actual { + actualMap[v.GetFullUrl()] = v + } + + for _, v := range actual { + if _, ok := expectedMap[v.GetFullUrl()]; !ok { + t.Error("Unexpected path:", v.GetFullUrl()) + } + } + for _, v := range expected { + if _, ok := actualMap[v.GetFullUrl()]; !ok { + t.Error("Path not found:", v.GetFullUrl()) + } + } } \ No newline at end of file diff --git a/artifactory/utils/moveutils.go b/artifactory/utils/moveutils.go index 0040c94d9..f3ee64051 100644 --- a/artifactory/utils/moveutils.go +++ b/artifactory/utils/moveutils.go @@ -54,18 +54,17 @@ func moveAql(fileSpec *File, flags *MoveFlags, moveType MoveType) (successCount, if err != nil { return } - LogSearchResults(len(resultItems)) successCount, failedCount, err = moveFiles("", resultItems, fileSpec, flags, moveType) return } func moveWildcard(fileSpec *File, flags *MoveFlags, moveType MoveType) (successCount, failedCount int, err error) { log.Info("Searching artifacts...") + fileSpec.IncludeDirs = "true" resultItems, err := AqlSearchDefaultReturnFields(fileSpec, flags) if err != nil { return } - LogSearchResults(len(resultItems)) regexpPath := cliutils.PathToRegExp(fileSpec.Pattern) successCount, failedCount, err = moveFiles(regexpPath, resultItems, fileSpec, flags, moveType) return @@ -74,7 +73,8 @@ func moveWildcard(fileSpec *File, flags *MoveFlags, moveType MoveType) (successC func moveFiles(regexpPath string, resultItems []AqlSearchResultItem, fileSpec *File, flags *MoveFlags, moveType MoveType) (successCount, failedCount int, err error) { successCount = 0 failedCount = 0 - + resultItems = ReduceDirResult(resultItems) + LogSearchResults(len(resultItems)) for _, v := range resultItems { destPathLocal := fileSpec.Target isFlat, e := cliutils.StringToBool(fileSpec.Flat, false) diff --git a/jfrog/artifactory_test.go b/jfrog/artifactory_test.go index 120c4ea77..56d85c065 100644 --- a/jfrog/artifactory_test.go +++ b/jfrog/artifactory_test.go @@ -90,6 +90,134 @@ func TestArtifactoryCopySingleFileNonFlat(t *testing.T) { cleanArtifactoryTest() } +func TestAqlFindingItemOnRoot(t *testing.T) { + initArtifactoryTest(t) + var filePath = "../testsdata/a+a/a*" + if runtime.GOOS == "windows" { + filePath = tests.FixWinPath("..\\testsdata\\a+a\\a*") + } + + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/path/inner/") + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/someFile", "--flat=true") + artifactoryCli.Exec("cp", tests.Repo1 + "/*", tests.Repo2) + isExistInArtifactory(tests.AnyItemCopy, tests.GetFilePath(tests.SearchRepo2), t) + artifactoryCli.Exec("del", tests.Repo2 + "/*", "--quiet=true") + artifactoryCli.Exec("del", tests.Repo1 + "/*", "--quiet=true") + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/path/") + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/someFile", "--flat=true") + artifactoryCli.Exec("cp", tests.Repo1 + "/*/", tests.Repo2) + isExistInArtifactory(tests.SingleFileCopy, tests.GetFilePath(tests.SearchRepo2), t) + cleanArtifactoryTest() +} + +func TestArtifactoryDirectoryCopy(t *testing.T) { + initArtifactoryTest(t) + var filePath = "../testsdata/a+a/a*" + if runtime.GOOS == "windows" { + filePath = tests.FixWinPath("..\\testsdata\\a+a\\a*") + } + + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/path/") + artifactoryCli.Exec("cp", tests.Repo1 + "/path/", tests.Repo2) + isExistInArtifactory(tests.SingleFileCopy, tests.GetFilePath(tests.SearchRepo2), t) + cleanArtifactoryTest() +} + +func TestArtifactoryDirectoryCopyUsingWildcard(t *testing.T) { + initArtifactoryTest(t) + var filePath = "../testsdata/a+a/a*" + if runtime.GOOS == "windows" { + filePath = tests.FixWinPath("..\\testsdata\\a+a\\a*") + } + + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/path/") + artifactoryCli.Exec("cp", tests.Repo1 + "/*/", tests.Repo2) + isExistInArtifactory(tests.SingleFileCopy, tests.GetFilePath(tests.SearchRepo2), t) + cleanArtifactoryTest() +} + +func TestArtifactoryDirectoryCopyUsingWildcardFlat(t *testing.T) { + initArtifactoryTest(t) + var filePath = "../testsdata/a+a/a*" + if runtime.GOOS == "windows" { + filePath = tests.FixWinPath("..\\testsdata\\a+a\\a*") + } + + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/path/inner/", ) + artifactoryCli.Exec("cp", tests.Repo1 + "/path/inner", tests.Repo2, "--flat=true") + isExistInArtifactory(tests.SingleDirectoryCopyFlat, tests.GetFilePath(tests.SearchRepo2), t) + cleanArtifactoryTest() +} + +func TestArtifactoryDirectoryCopyPatternEndsWithSlash(t *testing.T) { + initArtifactoryTest(t) + var filePath = "../testsdata/a+a/a*" + if runtime.GOOS == "windows" { + filePath = tests.FixWinPath("..\\testsdata\\a+a\\a*") + } + + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/path/inner/", ) + artifactoryCli.Exec("cp", tests.Repo1 + "/path/", tests.Repo2, "--flat=true") + isExistInArtifactory(tests.SingleDirectoryCopyFlat, tests.GetFilePath(tests.SearchRepo2), t) + cleanArtifactoryTest() +} + +func TestArtifactoryCopyAnyItemUsingWildcardFlat(t *testing.T) { + initArtifactoryTest(t) + var filePath = "../testsdata/a+a/a*" + if runtime.GOOS == "windows" { + filePath = tests.FixWinPath("..\\testsdata\\a+a\\a*") + } + + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/path/inner/", ) + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/someFile", "--flat=true") + artifactoryCli.Exec("cp", tests.Repo1 + "/*", tests.Repo2) + isExistInArtifactory(tests.AnyItemCopy, tests.GetFilePath(tests.SearchRepo2), t) + cleanArtifactoryTest() +} + +func TestArtifactoryCopyAnyItemRecursive(t *testing.T) { + initArtifactoryTest(t) + var filePath = "../testsdata/a+a/a*" + if runtime.GOOS == "windows" { + filePath = tests.FixWinPath("..\\testsdata\\a+a\\a*") + } + + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/a/b/", ) + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/aFile", "--flat=true") + artifactoryCli.Exec("cp", tests.Repo1 + "/a*", tests.Repo2, "--recursive=true") + isExistInArtifactory(tests.AnyItemCopyRecursive, tests.GetFilePath(tests.SearchRepo2), t) + cleanArtifactoryTest() +} + +func TestArtifactoryCopyAndRenameFolder(t *testing.T) { + initArtifactoryTest(t) + var filePath = "../testsdata/a+a/a*" + if runtime.GOOS == "windows" { + filePath = tests.FixWinPath("..\\testsdata\\a+a\\a*") + } + + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/path/inner/", ) + artifactoryCli.Exec("cp", tests.Repo1 + "/*", tests.Repo2 + "/newPath") + isExistInArtifactory(tests.CopyFolderRename, tests.GetFilePath(tests.SearchRepo2), t) + cleanArtifactoryTest() +} + +func TestArtifactoryCopyAnyItemUsingSpec(t *testing.T) { + initArtifactoryTest(t) + var filePath = "../testsdata/a+a/a*" + if runtime.GOOS == "windows" { + filePath = tests.FixWinPath("..\\testsdata\\a+a\\a*") + } + + specFile := tests.GetFilePath(tests.CopyItemsSpec) + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/path/inner/", ) + artifactoryCli.Exec("upload", filePath, tests.Repo1 + "/someFile", "--flat=true") + artifactoryCli.Exec("cp", "--spec=" + specFile) + isExistInArtifactory(tests.AnyItemCopyUsingSpec, tests.GetFilePath(tests.SearchRepo2), t) + cleanArtifactoryTest() +} + func TestArtifactoryUploadandExplode(t *testing.T) { initArtifactoryTest(t) artifactoryCli.Exec("upload", "../testsdata/a.zip", "jfrog-cli-tests-repo1", "--explode=true") @@ -309,7 +437,7 @@ func TestArtifactoryDeleteFolderWithWildcard(t *testing.T) { t.Error("Missing folder in artifactory : " + tests.Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/") } - artifactoryCli.Exec("delete", tests.Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/*/b/", "--quiet=true") + artifactoryCli.Exec("delete", tests.Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/*/b", "--quiet=true") resp, _, _, _ = httputils.SendGet(*tests.RtUrl + "api/storage/" + tests.Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/", true, artHttpDetails) if resp.StatusCode != 404 { t.Error("Couldn't delete folder in artifactory : " + tests.Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/") @@ -360,12 +488,12 @@ func TestArtifactoryDisplyedPathToDelete(t *testing.T) { specFile := tests.GetFilePath(tests.DeleteComplexSpec) artifactsToDelete := getPathsToDelete(specFile) - var displyedPaths []commands.SearchResult + var displayedPaths []commands.SearchResult for _, v := range artifactsToDelete { - displyedPaths = append(displyedPaths, commands.SearchResult{Path:v.Repo + "/" + v.Path + "/" + v.Name}) + displayedPaths = append(displayedPaths, commands.SearchResult{Path: v.GetFullUrl()}) } - tests.CompareExpectedVsActuals(tests.DeleteDisplyedFiles, displyedPaths, t) + tests.CompareExpectedVsActuals(tests.DeleteDisplyedFiles, displayedPaths, t) cleanArtifactoryTest() } @@ -887,9 +1015,10 @@ func TestArtifactoryCleanBuildInfo(t *testing.T) { func TestCollectGitBuildInfo(t *testing.T) { initArtifactoryTest(t) + gitCollectCliRunner := tests.NewJfrogCli(main, "jfrog rt", "") buildName, buildNumber := "cli-test-build", "13" - dotGitPath := getCliDotGitPath(t) - artifactoryCli.Exec("build-add-git", buildName, buildNumber, dotGitPath) + dotGitPath := tests.FixWinPath(getCliDotGitPath(t)) + gitCollectCliRunner.Exec("build-add-git", buildName, buildNumber, dotGitPath) //publish buildInfo artifactoryCli.Exec("build-publish", buildName, buildNumber) diff --git a/testsdata/specs/common/copy_items_spec.json b/testsdata/specs/common/copy_items_spec.json new file mode 100644 index 000000000..33e097e65 --- /dev/null +++ b/testsdata/specs/common/copy_items_spec.json @@ -0,0 +1,10 @@ +{ + "files": [ + { + "pattern": "jfrog-cli-tests-repo1/*/", + "target": "jfrog-cli-tests-repo2/", + "flat": "true", + "recursive": "true" + } + ] +} \ No newline at end of file diff --git a/testsdata/specs/common/move_copy_delete_spec.json b/testsdata/specs/common/move_copy_delete_spec.json index a752836e8..f34aaf6af 100644 --- a/testsdata/specs/common/move_copy_delete_spec.json +++ b/testsdata/specs/common/move_copy_delete_spec.json @@ -1,7 +1,7 @@ { "files": [ { - "pattern": "jfrog-cli-tests-repo2/flat_recursive_source/a/*", + "pattern": "jfrog-cli-tests-repo2/flat_recursive_source/a/*.in", "target": "jfrog-cli-tests-repo2/flat_recursive_target/", "flat": "true", "recursive": "true" @@ -13,19 +13,19 @@ "recursive": "true" }, { - "pattern": "jfrog-cli-tests-repo2/flat_nonrecursive_source/a/*", + "pattern": "jfrog-cli-tests-repo2/flat_nonrecursive_source/a/*.in", "target": "jfrog-cli-tests-repo2/flat_nonrecursive_target/", "flat": "true", "recursive": "false" }, { - "pattern": "jfrog-cli-tests-repo2/nonflat_recursive_source/a/*", + "pattern": "jfrog-cli-tests-repo2/nonflat_recursive_source/a/*.in", "target": "jfrog-cli-tests-repo2/nonflat_recursive_target/", "flat": "false", "recursive": "true" }, { - "pattern": "jfrog-cli-tests-repo2/nonflat_nonrecursive_source/a/*", + "pattern": "jfrog-cli-tests-repo2/nonflat_nonrecursive_source/a/*.in", "target": "jfrog-cli-tests-repo2/nonflat_nonrecursive_target/", "flat": "false", "recursive": "false" diff --git a/testsdata/specs/common/prepare_copy.json b/testsdata/specs/common/prepare_copy.json index 7328c4bb2..52f4f5d03 100644 --- a/testsdata/specs/common/prepare_copy.json +++ b/testsdata/specs/common/prepare_copy.json @@ -51,8 +51,8 @@ "flat": "true", "recursive": "true" },{ - "pattern": "jfrog-cli-tests-repo1/downloadTestResources/a/(*)", - "target": "jfrog-cli-tests-repo2/properties_source/a/{1}", + "pattern": "jfrog-cli-tests-repo1/downloadTestResources/a/", + "target": "jfrog-cli-tests-repo2/properties_source/a/", "flat": "true", "recursive": "true" },{ diff --git a/utils/tests/artifactoryconsts.go b/utils/tests/artifactoryconsts.go index 0010e58c5..712ccd544 100644 --- a/utils/tests/artifactoryconsts.go +++ b/utils/tests/artifactoryconsts.go @@ -29,6 +29,7 @@ const ( MoveRepositoryConfig = "move_repository_config.json" SpecsTestRepositoryConfig = "specs_test_repository_config.json" RepoDetailsUrl = "api/repositories/" + CopyItemsSpec = "copy_items_spec.json" ) var TxtUploadExpectedRepo1 = []string{ @@ -55,6 +56,28 @@ var SingleFileCopy = []string{ Repo2 + "/path/a1.in", } +var SingleDirectoryCopyFlat = []string{ + Repo2 + "/inner/a1.in", +} + +var AnyItemCopy = []string{ + Repo2 + "/path/inner/a1.in", + Repo2 + "/someFile", +} + +var AnyItemCopyRecursive = []string{ + Repo2 + "/a/b/a1.in", + Repo2 + "/aFile", +} + +var CopyFolderRename = []string{ + Repo2 + "/newPath/inner/a1.in", +} + +var AnyItemCopyUsingSpec = []string{ + Repo2 + "/inner/a1.in", +} + var ExplodeUploadExpectedRepo1 = []string{ Repo1 + "/a/a3.in", Repo1 + "/a/a1.in", @@ -86,12 +109,12 @@ var MassiveMoveExpected = []string{ Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/a1.in", Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/a2.in", Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/a3.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b1.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b2.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b3.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/c/c1.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/c/c2.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/c/c3.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/b1.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/b2.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/b3.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/c/c1.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/c/c2.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/c/c3.in", Repo2 + "/flat_nonrecursive_target/a1.in", Repo2 + "/flat_nonrecursive_target/a2.in", Repo2 + "/flat_nonrecursive_target/a3.in", @@ -107,33 +130,33 @@ var MassiveMoveExpected = []string{ Repo2 + "/no_target/a/a1.in", Repo2 + "/no_target/a/a2.in", Repo2 + "/no_target/a/a3.in", - Repo2 + "/no_target/a/b/b1.in", - Repo2 + "/no_target/a/b/b2.in", - Repo2 + "/no_target/a/b/b3.in", - Repo2 + "/no_target/a/b/c/c1.in", - Repo2 + "/no_target/a/b/c/c2.in", - Repo2 + "/no_target/a/b/c/c3.in", + Repo2 + "/no_target/a/b/b/b1.in", + Repo2 + "/no_target/a/b/b/b2.in", + Repo2 + "/no_target/a/b/b/b3.in", + Repo2 + "/no_target/a/b/b/c/c1.in", + Repo2 + "/no_target/a/b/b/c/c2.in", + Repo2 + "/no_target/a/b/b/c/c3.in", Repo2 + "/nonflat_nonrecursive_target/nonflat_nonrecursive_source/a/a1.in", Repo2 + "/nonflat_nonrecursive_target/nonflat_nonrecursive_source/a/a2.in", Repo2 + "/nonflat_nonrecursive_target/nonflat_nonrecursive_source/a/a3.in", Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/a1.in", Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/a2.in", Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/a3.in", - Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/b1.in", - Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/b2.in", - Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/b3.in", - Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/c/c1.in", - Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/c/c2.in", - Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/c/c3.in", + Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/b/b1.in", + Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/b/b2.in", + Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/b/b3.in", + Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/b/c/c1.in", + Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/b/c/c2.in", + Repo2 + "/nonflat_recursive_target/nonflat_recursive_source/a/b/b/c/c3.in", Repo2 + "/pattern_placeholder_target/a/a1.in", Repo2 + "/pattern_placeholder_target/a/a2.in", Repo2 + "/pattern_placeholder_target/a/a3.in", - Repo2 + "/pattern_placeholder_target/a/b/b1.in", - Repo2 + "/pattern_placeholder_target/a/b/b2.in", - Repo2 + "/pattern_placeholder_target/a/b/b3.in", - Repo2 + "/pattern_placeholder_target/a/b/c/c1.in", - Repo2 + "/pattern_placeholder_target/a/b/c/c2.in", - Repo2 + "/pattern_placeholder_target/a/b/c/c3.in", + Repo2 + "/pattern_placeholder_target/a/b/b/b1.in", + Repo2 + "/pattern_placeholder_target/a/b/b/b2.in", + Repo2 + "/pattern_placeholder_target/a/b/b/b3.in", + Repo2 + "/pattern_placeholder_target/a/b/b/c/c1.in", + Repo2 + "/pattern_placeholder_target/a/b/b/c/c2.in", + Repo2 + "/pattern_placeholder_target/a/b/b/c/c3.in", Repo2 + "/properties_target/properties_source/a/a1.in", Repo2 + "/properties_target/properties_source/a/a2.in", Repo2 + "/properties_target/properties_source/a/a3.in", @@ -344,12 +367,12 @@ var Delete1 = []string{ Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/a1.in", Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/a2.in", Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/a3.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b1.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b2.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b3.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/c/c1.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/c/c2.in", - Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/c/c3.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/b1.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/b2.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/b3.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/c/c1.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/c/c2.in", + Repo2 + "/defaults_recursive_nonflat_target/defaults_recursive_nonflat_source/a/b/b/c/c3.in", Repo2 + "/flat_nonrecursive_target/a1.in", Repo2 + "/flat_nonrecursive_target/a2.in", Repo2 + "/flat_nonrecursive_target/a3.in", @@ -365,12 +388,12 @@ var Delete1 = []string{ Repo2 + "/no_target/a/a1.in", Repo2 + "/no_target/a/a2.in", Repo2 + "/no_target/a/a3.in", - Repo2 + "/no_target/a/b/b1.in", - Repo2 + "/no_target/a/b/b2.in", - Repo2 + "/no_target/a/b/b3.in", - Repo2 + "/no_target/a/b/c/c1.in", - Repo2 + "/no_target/a/b/c/c2.in", - Repo2 + "/no_target/a/b/c/c3.in", + Repo2 + "/no_target/a/b/b/b1.in", + Repo2 + "/no_target/a/b/b/b2.in", + Repo2 + "/no_target/a/b/b/b3.in", + Repo2 + "/no_target/a/b/b/c/c1.in", + Repo2 + "/no_target/a/b/b/c/c2.in", + Repo2 + "/no_target/a/b/b/c/c3.in", Repo2 + "/nonflat_nonrecursive_target/nonflat_nonrecursive_source/a/a1.in", Repo2 + "/nonflat_nonrecursive_target/nonflat_nonrecursive_source/a/a2.in", Repo2 + "/nonflat_nonrecursive_target/nonflat_nonrecursive_source/a/a3.in", @@ -380,12 +403,12 @@ var Delete1 = []string{ Repo2 + "/pattern_placeholder_target/a/a1.in", Repo2 + "/pattern_placeholder_target/a/a2.in", Repo2 + "/pattern_placeholder_target/a/a3.in", - Repo2 + "/pattern_placeholder_target/a/b/b1.in", - Repo2 + "/pattern_placeholder_target/a/b/b2.in", - Repo2 + "/pattern_placeholder_target/a/b/b3.in", - Repo2 + "/pattern_placeholder_target/a/b/c/c1.in", - Repo2 + "/pattern_placeholder_target/a/b/c/c2.in", - Repo2 + "/pattern_placeholder_target/a/b/c/c3.in", + Repo2 + "/pattern_placeholder_target/a/b/b/b1.in", + Repo2 + "/pattern_placeholder_target/a/b/b/b2.in", + Repo2 + "/pattern_placeholder_target/a/b/b/b3.in", + Repo2 + "/pattern_placeholder_target/a/b/b/c/c1.in", + Repo2 + "/pattern_placeholder_target/a/b/b/c/c2.in", + Repo2 + "/pattern_placeholder_target/a/b/b/c/c3.in", Repo2 + "/properties_target/properties_source/a/a1.in", Repo2 + "/properties_target/properties_source/a/a2.in", Repo2 + "/properties_target/properties_source/a/a3.in", @@ -401,23 +424,14 @@ var Delete1 = []string{ } var DeleteDisplyedFiles = []string{ + Repo2 + "/3_only_flat_recursive_source/a/b/", Repo2 + "/3_only_flat_recursive_source/a/a1.in", Repo2 + "/3_only_flat_recursive_source/a/a2.in", Repo2 + "/3_only_flat_recursive_source/a/a3.in", - Repo2 + "/flat_recursive_source/a/b/b1.in", - Repo2 + "/flat_recursive_source/a/b/b2.in", - Repo2 + "/flat_recursive_source/a/b/b3.in", - Repo2 + "/flat_recursive_source/a/b/c/c1.in", - Repo2 + "/flat_recursive_source/a/b/c/c2.in", - Repo2 + "/flat_recursive_source/a/b/c/c3.in", + Repo2 + "/flat_recursive_source/a/b/b/", Repo2 + "/defaults_recursive_nonflat_source/a/a1.in", Repo2 + "/defaults_recursive_nonflat_source/a/a2.in", Repo2 + "/defaults_recursive_nonflat_source/a/a3.in", - Repo2 + "/defaults_recursive_nonflat_source/a/b/b1.in", - Repo2 + "/defaults_recursive_nonflat_source/a/b/b2.in", - Repo2 + "/defaults_recursive_nonflat_source/a/b/b3.in", - Repo2 + "/defaults_recursive_nonflat_source/a/b/c/c1.in", - Repo2 + "/defaults_recursive_nonflat_source/a/b/c/c2.in", - Repo2 + "/defaults_recursive_nonflat_source/a/b/c/c3.in", - Repo2 + "/flat_nonrecursive_source/a/b/", + Repo2 + "/defaults_recursive_nonflat_source/a/b/", + Repo2 + "/flat_nonrecursive_source/a/b/b/", } \ No newline at end of file