From 634ff919c7288b37e1faa22805b6ae67547b9f8d Mon Sep 17 00:00:00 2001 From: sZma5a Date: Sun, 30 Jul 2023 16:23:20 +0900 Subject: [PATCH] include PAT information in URL Signed-off-by: sZma5a --- pkg/git/client.go | 33 ++++++++++++++++++++++++++++++++- pkg/git/client_test.go | 7 +++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/pkg/git/client.go b/pkg/git/client.go index 980f0f5038..1f4c79bd24 100644 --- a/pkg/git/client.go +++ b/pkg/git/client.go @@ -17,6 +17,7 @@ package git import ( "context" "fmt" + "net/url" "os" "os/exec" "path/filepath" @@ -48,6 +49,10 @@ type client struct { cacheDir string mu sync.Mutex repoLocks map[string]*sync.Mutex + pat struct { + userName string + userToken string + } gitEnvs []string gitEnvsByRepo map[string][]string @@ -90,6 +95,15 @@ func WithEmail(e string) Option { } } +func WithPAT(userName, userToken string) Option { + return func(c *client) { + if userName != "" && userToken != "" { + c.pat.userName = userName + c.pat.userToken = userToken + } + } +} + // NewClient creates a new CLient instance for cloning git repositories. // After using Clean should be called to delete cache data. func NewClient(opts ...Option) (Client, error) { @@ -131,10 +145,15 @@ func (c *client) Clone(ctx context.Context, repoID, remote, branch, destination ) ) + remote, err := includePatRemote(ctx, remote, c.pat.userName, c.pat.userToken) + if err != nil { + return nil, err + } + c.lockRepo(repoID) defer c.unlockRepo(repoID) - _, err := os.Stat(repoCachePath) + _, err = os.Stat(repoCachePath) if err != nil && !os.IsNotExist(err) { return nil, err } @@ -260,6 +279,18 @@ func (c *client) envsForRepo(remote string) []string { return append(envs, c.gitEnvs...) } +func includePatRemote(ctx context.Context, remote, userName, userToken string) (string, error) { + if userName == "" || userToken == "" { + return remote, nil + } + u, err := parseGitURL(remote) + if err != nil { + return "", fmt.Errorf("failed to include pat: %v", err) + } + u.User = url.UserPassword(userName, userToken) + return u.String(), nil +} + func runGitCommand(ctx context.Context, execPath, dir string, envs []string, args ...string) ([]byte, error) { cmd := exec.CommandContext(ctx, execPath, args...) cmd.Dir = dir diff --git a/pkg/git/client_test.go b/pkg/git/client_test.go index 340c2a1550..e2da18a2bc 100644 --- a/pkg/git/client_test.go +++ b/pkg/git/client_test.go @@ -176,6 +176,13 @@ func (g gitCommander) addCommit(filename string, content string) error { }) } +func TestCloneUsingPAT(t *testing.T) { + ctx := context.Background() + url, err := includePatRemote(ctx, "https://example.com/org/repo", "test-user", "test-token") + require.NoError(t, err) + assert.Equal(t, "https://test-user:test-token@example.com/org/repo", url) +} + func TestRetryCommand(t *testing.T) { var ( ranCount = 0