diff --git a/cmd/import.go b/cmd/import.go index 66ffc94..8f2b1d7 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -43,9 +43,10 @@ import cycle.`, recurseSubmodules, _ := cmd.Flags().GetBool("recurse-submodules") var hardCodedExcludeList = []string{} + var clonedPaths []string // Import repository files in the given file - validFile, hardCodedExcludeList := singleCloneSweep(cloningPath, filePath, numWorkers, overwriteExisting, shallowClone, numRetries, recurseSubmodules) + validFile, hardCodedExcludeList, clonedPaths := singleCloneSweep(cloningPath, filePath, numWorkers, overwriteExisting, shallowClone, numRetries, recurseSubmodules) if !validFile { os.Exit(1) } @@ -53,7 +54,7 @@ import cycle.`, os.Exit(0) } excludeList = append(excludeList, hardCodedExcludeList...) - nestedImportClones(cloningPath, filePath, depthRecursive, numWorkers, overwriteExisting, shallowClone, numRetries, excludeList, recurseSubmodules) + nestedImportClones(cloningPath, filePath, depthRecursive, numWorkers, overwriteExisting, shallowClone, numRetries, excludeList, recurseSubmodules, clonedPaths) }, } @@ -72,17 +73,18 @@ func init() { importCmd.Flags().BoolP("recurse-submodules", "s", false, "Recursively clone submodules") } -func singleCloneSweep(root string, filePath string, numWorkers int, overwriteExisting bool, shallowClone bool, numRetries int, recurseSubmodules bool) (bool, []string) { +func singleCloneSweep(root string, filePath string, numWorkers int, overwriteExisting bool, shallowClone bool, numRetries int, recurseSubmodules bool) (bool, []string, []string) { utils.PrintSeparator() utils.PrintSection(fmt.Sprintf("Importing from %s", filePath)) utils.PrintSeparator() config, err := utils.ParseReposFile(filePath) var allExcludes []string + var clonedPaths []string if err != nil { utils.PrintErrorMsg(fmt.Sprintf("Invalid file given {%s}. %s\n", filePath, err)) - return false, allExcludes + return false, allExcludes, clonedPaths } // Create a channel to send work to the workers with a buffer size of length gitRepos jobs := make(chan utils.RepositoryJob, len(config.Repositories)) @@ -106,6 +108,7 @@ func singleCloneSweep(root string, filePath string, numWorkers int, overwriteExi for range numRetries { success = utils.PrintGitClone(job.Repo.URL, job.Repo.Version, job.RepoPath, overwriteExisting, shallowClone, false, recurseSubmodules) if success { + clonedPaths = append(clonedPaths, job.RepoPath) break } } @@ -141,10 +144,10 @@ func singleCloneSweep(root string, filePath string, numWorkers int, overwriteExi } } - return validFile, allExcludes + return validFile, allExcludes, clonedPaths } -func nestedImportClones(cloningPath string, initialFilePath string, depthRecursive int, numWorkers int, overwriteExisting bool, shallowClone bool, numRetries int, excludeList []string, recurseSubmodules bool) { +func nestedImportClones(cloningPath string, initialFilePath string, depthRecursive int, numWorkers int, overwriteExisting bool, shallowClone bool, numRetries int, excludeList []string, recurseSubmodules bool, clonedPaths []string) { // Recursively import .repos files found clonedReposFiles := map[string]bool{initialFilePath: true} validFiles := true @@ -159,7 +162,7 @@ func nestedImportClones(cloningPath string, initialFilePath string, depthRecursi } // Find .repos file to clone - foundReposFiles, err := utils.FindReposFiles(cloningPath) + foundReposFiles, err := utils.FindReposFiles(cloningPath, clonedPaths) if err != nil || len(foundReposFiles) == 0 { break } @@ -203,9 +206,11 @@ func nestedImportClones(cloningPath string, initialFilePath string, depthRecursi clonedReposFiles[filePathToClone] = false continue } - validFiles, hardCodedExcludeList = singleCloneSweep(cloningPath, filePathToClone, numWorkers, overwriteExisting, shallowClone, numRetries, recurseSubmodules) + var newClonedPaths []string + validFiles, hardCodedExcludeList, newClonedPaths = singleCloneSweep(cloningPath, filePathToClone, numWorkers, overwriteExisting, shallowClone, numRetries, recurseSubmodules) clonedReposFiles[filePathToClone] = true newReposFileFound = true + clonedPaths = append(clonedPaths, newClonedPaths...) if !validFiles { utils.PrintErrorMsg("Encountered errors while importing file") os.Exit(1) diff --git a/test/git_helpers_test.go b/test/git_helpers_test.go index b5b3674..0efb603 100644 --- a/test/git_helpers_test.go +++ b/test/git_helpers_test.go @@ -194,12 +194,15 @@ func TestCloneGitRepo(t *testing.T) { if utils.GitClone("https://github.com/ros2/sadasdasd.git", "", "/tmp/testdata/sdasda", false, false, false, false) != utils.FailedClone { t.Errorf("Expected to fail to clone git repository") } - if utils.GitClone("https://github.com/ros2/demos.git", "", repoPath, false, false, false, false) != utils.SkippedClone { + if utils.GitClone("https://github.com/ros2/demos.git", "rolling", repoPath, false, false, false, false) != utils.SkippedClone { t.Errorf("Expected to skip to clone git repository") } if utils.GitClone("https://github.com/ros2/demos.git", "", repoPath, true, false, false, false) != utils.SuccessfullClone { t.Errorf("Expected to overwrite found git repository") } + if utils.GitClone("https://github.com/ros2/demos.git", "jazzy", repoPath, false, false, false, false) != utils.SwitchedBranch { + t.Errorf("Expected to successfully to switch to a branch") + } if utils.GitClone("https://github.com/ros2/demos.git", "", repoPath, true, true, false, false) != utils.SuccessfullClone { t.Errorf("Expected to successfully to clone git repository with shallow enabled") } diff --git a/test/repos_helpers_test.go b/test/repos_helpers_test.go index 803278e..589c616 100644 --- a/test/repos_helpers_test.go +++ b/test/repos_helpers_test.go @@ -81,16 +81,21 @@ func TestParsingReposFile(t *testing.T) { } func TestFindingReposFiles(t *testing.T) { - foundReposFiles, err := utils.FindReposFiles(".") + foundReposFiles, err := utils.FindReposFiles(".", nil) if err != nil || len(foundReposFiles) == 0 { t.Errorf("Expected to find at least one .repos file %v", err) } - foundReposFiles, err = utils.FindReposFiles("../cmd/") + foundReposFiles, err = utils.FindReposFiles("../cmd/", nil) if err != nil || len(foundReposFiles) != 0 { t.Errorf("Expected to not find any .repos file %v", err) } + + foundReposFiles, err = utils.FindReposFiles(".", []string{"../test"}) + if err != nil || len(foundReposFiles) == 0 { + t.Errorf("Expected to find at least one .repos file %v", err) + } } func TestFindDirectory(t *testing.T) { diff --git a/utils/git_helpers.go b/utils/git_helpers.go index 72e0543..1062f70 100644 --- a/utils/git_helpers.go +++ b/utils/git_helpers.go @@ -17,6 +17,7 @@ const ( SuccessfullClone = iota SkippedClone FailedClone + SwitchedBranch ) // IsGitRepository checks if a directory is a git repository @@ -213,9 +214,10 @@ func IsValidSha(sha string) bool { func GitClone(url string, version string, clonePath string, overwriteExisting bool, shallowClone bool, enablePrompt bool, recurseSubmodules bool) int { // Check if clonePath exists + var skip_clone bool = false if _, err := os.Stat(clonePath); err == nil { if !overwriteExisting { - return SkippedClone + skip_clone = true } else { // Remove existing clonePath if err := os.RemoveAll(clonePath); err != nil { @@ -250,14 +252,28 @@ func GitClone(url string, version string, clonePath string, overwriteExisting bo cmdArgs = append(cmdArgs, "--shallow-submodules") } } - if _, err := RunGitCmd(".", "clone", envConfig, cmdArgs...); err != nil { - return FailedClone + if !skip_clone { + if _, err := RunGitCmd(".", "clone", envConfig, cmdArgs...); err != nil { + return FailedClone + } + } + + if skip_clone && (GetGitCommitSha(clonePath) == version || GetGitBranch(clonePath) == version) { + return SkippedClone } if versionIsSha { if _, err := GitSwitch(clonePath, version, false, true); err != nil { return FailedClone } + if skip_clone { + return SwitchedBranch + } + } else if skip_clone { + if _, err := GitSwitch(clonePath, version, false, false); err != nil { + return FailedClone + } + return SwitchedBranch } return SuccessfullClone @@ -328,6 +344,9 @@ func PrintGitClone(url string, version string, path string, overwriteExisting bo case FailedClone: cloneMsg = fmt.Sprintf("%sFailed to clone git repository '%s' with version '%s'%s\n", RedColor, url, version, ResetColor) cloneSuccessful = false + case SwitchedBranch: + cloneMsg = fmt.Sprintf("Successfully switched to version '%s' in existing git repository '%s'\n", version, url) + cloneSuccessful = true default: panic("Unexpected behavior!") } diff --git a/utils/repos_helpers.go b/utils/repos_helpers.go index 984fc3c..6f549af 100644 --- a/utils/repos_helpers.go +++ b/utils/repos_helpers.go @@ -108,17 +108,32 @@ func ParseReposFile(filePath string) (*Config, error) { } // FindReposFiles Search .repos files in a given path -func FindReposFiles(rootPath string) ([]string, error) { +func FindReposFiles(rootPath string, clonedPaths []string) ([]string, error) { var foundReposFiles []string - err := filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error { - if !info.IsDir() && filepath.Ext(path) == ".repos" { + var err error + if len(clonedPaths) == 0 { + err = filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error { if err != nil { return err } - foundReposFiles = append(foundReposFiles, path) + if !info.IsDir() && (filepath.Ext(path) == ".repos") { + foundReposFiles = append(foundReposFiles, path) + } + return nil + }) + } else { + for _, clonedPath := range clonedPaths { + err = filepath.Walk(clonedPath, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() && (filepath.Ext(path) == ".repos") { + foundReposFiles = append(foundReposFiles, path) + } + return nil + }) } - return nil - }) + } return foundReposFiles, err }