diff --git a/cmd/golangBuild.go b/cmd/golangBuild.go index 9fae08a00..c746d356b 100644 --- a/cmd/golangBuild.go +++ b/cmd/golangBuild.go @@ -7,7 +7,6 @@ import ( "os" "path" "path/filepath" - "regexp" "strings" "github.com/SAP/jenkins-library/pkg/buildsettings" @@ -24,7 +23,6 @@ import ( "github.com/SAP/jenkins-library/pkg/versioning" "golang.org/x/mod/modfile" - "golang.org/x/mod/module" ) const ( @@ -341,26 +339,11 @@ func prepareGolangEnvironment(config *golangBuildOptions, goModFile *modfile.Fil // pass private repos to go process os.Setenv("GOPRIVATE", config.PrivateModules) - repoURLs, err := lookupGolangPrivateModulesRepositories(goModFile, config.PrivateModules, utils) - + err = gitConfigurationForPrivateModules(config.PrivateModules, config.PrivateModulesGitToken, utils) if err != nil { return err } - // configure credentials git shall use for pulling repos - for _, repoURL := range repoURLs { - if match, _ := regexp.MatchString("(?i)^https?://", repoURL); !match { - continue - } - - authenticatedRepoURL := strings.Replace(repoURL, "://", fmt.Sprintf("://%s@", config.PrivateModulesGitToken), 1) - - err = utils.RunExecutable("git", "config", "--global", fmt.Sprintf("url.%s.insteadOf", authenticatedRepoURL), repoURL) - if err != nil { - return err - } - } - return nil } @@ -539,36 +522,6 @@ func runGolangBuildPerArchitecture(config *golangBuildOptions, goModFile *modfil return binaryNames, nil } -// lookupPrivateModulesRepositories returns a slice of all modules that match the given glob pattern -func lookupGolangPrivateModulesRepositories(goModFile *modfile.File, globPattern string, utils golangBuildUtils) ([]string, error) { - if globPattern == "" { - return []string{}, nil - } - - if goModFile == nil { - return nil, fmt.Errorf("couldn't find go.mod file") - } else if goModFile.Require == nil { - return []string{}, nil // no modules referenced, nothing to do - } - - privateModules := []string{} - - for _, goModule := range goModFile.Require { - if !module.MatchPrefixPatterns(globPattern, goModule.Mod.Path) { - continue - } - - repo, err := utils.GetRepositoryURL(goModule.Mod.Path) - - if err != nil { - return nil, err - } - - privateModules = append(privateModules, repo) - } - return privateModules, nil -} - func runBOMCreation(utils golangBuildUtils, outputFilename string) error { if err := utils.RunExecutable("cyclonedx-gomod", "mod", "-licenses", fmt.Sprintf("-verbose=%t", GeneralConfig.Verbose), "-test", "-output", outputFilename, "-output-version", "1.4"); err != nil { @@ -631,3 +584,20 @@ func isMainPackage(utils golangBuildUtils, pkg string) (bool, error) { return true, nil } + +func gitConfigurationForPrivateModules(privateMod string, token string, utils golangBuildUtils) error { + privateMod = strings.ReplaceAll(privateMod, "/*", "") + privateMod = strings.ReplaceAll(privateMod, "*.", "") + modules := strings.Split(privateMod, ",") + for _, v := range modules { + authenticatedRepoURL := fmt.Sprintf("https://%s@%s", token, v) + repoBaseURL := fmt.Sprintf("https://%s", v) + err := utils.RunExecutable("git", "config", "--global", fmt.Sprintf("url.%s.insteadOf", authenticatedRepoURL), repoBaseURL) + if err != nil { + return err + } + + } + + return nil +} diff --git a/cmd/golangBuild_test.go b/cmd/golangBuild_test.go index 8709cb0e3..93f2d4cb2 100644 --- a/cmd/golangBuild_test.go +++ b/cmd/golangBuild_test.go @@ -911,8 +911,7 @@ go 1.17` expect: expectations{ envVars: []string{"GOPRIVATE=*.example.com"}, commandsExecuted: [][]string{ - {"git", "config", "--global", "url.https://secret@private1.example.com/private/repo.git.insteadOf", "https://private1.example.com/private/repo.git"}, - {"git", "config", "--global", "url.https://secret@private2.example.com/another/repo.git.insteadOf", "https://private2.example.com/another/repo.git"}, + {"git", "config", "--global", "url.https://secret@example.com.insteadOf", "https://example.com"}, }, }, }, @@ -943,89 +942,6 @@ go 1.17` } } -func TestLookupGolangPrivateModulesRepositories(t *testing.T) { - t.Parallel() - - modTestFile := ` -module private.example.com/m - -require ( - example.com/public/module v1.0.0 - private1.example.com/private/repo v0.1.0 - private2.example.com/another/repo v0.2.0 -) - -go 1.17` - - type expectations struct { - repos []string - errorMessage string - } - tests := []struct { - name string - modFileContent string - globPattern string - expect expectations - }{ - { - name: "Does nothing if glob pattern is empty", - modFileContent: modTestFile, - expect: expectations{ - repos: []string{}, - }, - }, - { - name: "Does nothing if there is no go.mod file", - globPattern: "private.example.com", - modFileContent: "", - expect: expectations{ - repos: []string{}, - }, - }, - { - name: "Detects all private repos using a glob pattern", - modFileContent: modTestFile, - globPattern: "*.example.com", - expect: expectations{ - repos: []string{"https://private1.example.com/private/repo.git", "https://private2.example.com/another/repo.git"}, - }, - }, - { - name: "Detects all private repos", - modFileContent: modTestFile, - globPattern: "private1.example.com,private2.example.com", - expect: expectations{ - repos: []string{"https://private1.example.com/private/repo.git", "https://private2.example.com/another/repo.git"}, - }, - }, - { - name: "Detects a dedicated repo", - modFileContent: modTestFile, - globPattern: "private2.example.com", - expect: expectations{ - repos: []string{"https://private2.example.com/another/repo.git"}, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - utils := newGolangBuildTestsUtils() - - goModFile, _ := modfile.Parse("", []byte(tt.modFileContent), nil) - - repos, err := lookupGolangPrivateModulesRepositories(goModFile, tt.globPattern, utils) - - if tt.expect.errorMessage == "" { - assert.NoError(t, err) - assert.Equal(t, tt.expect.repos, repos) - } else { - assert.EqualError(t, err, tt.expect.errorMessage) - } - }) - } -} - func TestRunGolangciLint(t *testing.T) { t.Parallel() @@ -1153,3 +1069,59 @@ func TestRetrieveGolangciLint(t *testing.T) { }) } } + +func Test_gitConfigurationForPrivateModules(t *testing.T) { + type args struct { + privateMod string + token string + } + type expectations struct { + commandsExecuted [][]string + } + tests := []struct { + name string + args args + + expected expectations + }{ + { + name: "with one private module", + args: args{ + privateMod: "example.com/*", + token: "mytoken", + }, + expected: expectations{ + commandsExecuted: [][]string{ + {"git", "config", "--global", "url.https://mytoken@example.com.insteadOf", "https://example.com"}, + }, + }, + }, + { + name: "with multiple private modules", + args: args{ + privateMod: "example.com/*,test.com/*", + token: "mytoken", + }, + expected: expectations{ + commandsExecuted: [][]string{ + {"git", "config", "--global", "url.https://mytoken@example.com.insteadOf", "https://example.com"}, + {"git", "config", "--global", "url.https://mytoken@test.com.insteadOf", "https://test.com"}, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + utils := newGolangBuildTestsUtils() + + err := gitConfigurationForPrivateModules(tt.args.privateMod, tt.args.token, utils) + + if assert.NoError(t, err) { + for i, expectedCommand := range tt.expected.commandsExecuted { + assert.Equal(t, expectedCommand[0], utils.Calls[i].Exec) + assert.Equal(t, expectedCommand[1:], utils.Calls[i].Params) + } + } + }) + } +}