From 77ce9d30a593762b37661f9c1477c81f4c5aac5d Mon Sep 17 00:00:00 2001 From: Bruno Meneguele Date: Wed, 18 Nov 2020 12:28:33 -0300 Subject: [PATCH] Allow using HTTP protocol instead of SSH In some cases (internal instances of gitlab or even user preference) HTTP is the only way of fetching data from gitlab. Commit 3e3b74d3d717 ("Make http default fork") make 'lab fork' to use HTTP by default, but it doesn't consider other cases where the user may also need to uso HTTP. Another point is that it turns SSH off completely. This patch, instead, adds the HTTP support as an additional command flag (--http), where possible, but let SSH as the default protocol: it has been the default since day zero. Signed-off-by: Bruno Meneguele --- cmd/clone.go | 7 +++++-- cmd/fork.go | 8 ++++++-- cmd/mr_checkout.go | 5 ++++- cmd/mr_show.go | 5 +++-- cmd/project_create.go | 11 ++++++++--- cmd/util.go | 10 ++++++++++ cmd/util_test.go | 17 +++++++++++++++++ internal/gitlab/gitlab.go | 17 ++++++++++++----- 8 files changed, 65 insertions(+), 15 deletions(-) diff --git a/cmd/clone.go b/cmd/clone.go index 73e66cd9..8c25221c 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -32,7 +32,7 @@ var cloneCmd = &cobra.Command{ } else if err != nil { log.Fatal(err) } - path := project.SSHURLToRepo + path := labURLToRepo(project) // #116 retry on the cases where we found a project but clone // failed over ssh err = retry.Do(func() error { @@ -57,7 +57,8 @@ var cloneCmd = &cobra.Command{ if err != nil { log.Fatal(err) } - err = git.RemoteAdd("upstream", ffProject.SSHURLToRepo, "./"+dir) + urlToRepo := labURLToRepo(ffProject) + err = git.RemoteAdd("upstream", urlToRepo, "./"+dir) if err != nil { log.Fatal(err) } @@ -66,5 +67,7 @@ var cloneCmd = &cobra.Command{ } func init() { + // useHTTP is defined in "project_create.go" + cloneCmd.Flags().BoolVar(&useHTTP, "http", false, "clone using HTTP protocol instead of SSH") RootCmd.AddCommand(cloneCmd) } diff --git a/cmd/fork.go b/cmd/fork.go index 487eadea..87fb030c 100644 --- a/cmd/fork.go +++ b/cmd/fork.go @@ -54,7 +54,7 @@ func forkFromOrigin(cmd *cobra.Command, args []string) { if err != nil { log.Fatal(err) } - forkRemoteURL, err := lab.Fork(project) + forkRemoteURL, err := lab.Fork(project, useHTTP) if err != nil { log.Fatal(err) } @@ -66,7 +66,9 @@ func forkFromOrigin(cmd *cobra.Command, args []string) { } } func forkToUpstream(cmd *cobra.Command, args []string) { - _, err := lab.Fork(args[0]) + // lab.Fork doesn't have access to the useHTTP var, so we need to pass + // this info to that, so the process works correctly. + _, err := lab.Fork(args[0], useHTTP) if err != nil { log.Fatal(err) } @@ -90,5 +92,7 @@ func determineForkRemote(project string) string { func init() { forkCmd.Flags().BoolP("skip-clone", "s", false, "skip clone after remote fork") + // useHTTP is defined in "project_create.go" + forkCmd.Flags().BoolVar(&useHTTP, "http", false, "fork using HTTP protocol instead of SSH") RootCmd.AddCommand(forkCmd) } diff --git a/cmd/mr_checkout.go b/cmd/mr_checkout.go index 39a5ae02..3e546b7f 100644 --- a/cmd/mr_checkout.go +++ b/cmd/mr_checkout.go @@ -71,7 +71,8 @@ var checkoutCmd = &cobra.Command{ if err != nil { log.Fatal(err) } - if err := git.RemoteAdd(mr.Author.Username, mrProject.SSHURLToRepo, "."); err != nil { + urlToRepo := labURLToRepo(mrProject) + if err := git.RemoteAdd(mr.Author.Username, urlToRepo, "."); err != nil { log.Fatal(err) } } @@ -108,6 +109,8 @@ var checkoutCmd = &cobra.Command{ func init() { checkoutCmd.Flags().StringVarP(&mrCheckoutCfg.branch, "branch", "b", "", "checkout merge request with name") checkoutCmd.Flags().BoolVarP(&mrCheckoutCfg.track, "track", "t", false, "set checked out branch to track mr author remote branch, adds remote if needed") + // useHTTP is defined in "project_create.go" + checkoutCmd.Flags().BoolVar(&useHTTP, "http", false, "checkout using HTTP protocol instead of SSH") mrCmd.AddCommand(checkoutCmd) carapace.Gen(checkoutCmd).PositionalCompletion( carapace.ActionCallback(func(args []string) carapace.Action { diff --git a/cmd/mr_show.go b/cmd/mr_show.go index 5d5d1a58..c32f6a6d 100644 --- a/cmd/mr_show.go +++ b/cmd/mr_show.go @@ -99,7 +99,8 @@ func findLocalRemote(ProjectID int) string { for r := range remotes { // The fetch and push entries can be different for a remote. // Only the fetch entry is useful. - if strings.Contains(remotes[r], project.SSHURLToRepo+" (fetch)") { + if strings.Contains(remotes[r], project.SSHURLToRepo+" (fetch)") || + strings.Contains(remotes[r], project.HTTPURLToRepo+" (fetch)") { found := strings.Split(remotes[r], "\t") remote = found[0] break @@ -107,7 +108,7 @@ func findLocalRemote(ProjectID int) string { } if remote == "" { - log.Fatal("remote for ", project.SSHURLToRepo, "not found in local remotes") + log.Fatal("remote for ", project.NameWithNamespace, "not found in local remotes") } return remote } diff --git a/cmd/project_create.go b/cmd/project_create.go index c18c4ce9..0ff46809 100644 --- a/cmd/project_create.go +++ b/cmd/project_create.go @@ -11,8 +11,11 @@ import ( lab "github.com/zaquestion/lab/internal/gitlab" ) -// private and public are defined in snippet_create.go -var internal bool +var ( + // private and public are defined in snippet_create.go + internal bool + useHTTP bool +) // projectCreateCmd represents the create command var projectCreateCmd = &cobra.Command{ @@ -68,7 +71,8 @@ lab project create -n "new proj" # user/new-proj named "new proj"`, log.Fatal(err) } if git.InsideGitRepo() { - err = git.RemoteAdd("origin", p.SSHURLToRepo, ".") + urlToRepo := labURLToRepo(p) + err = git.RemoteAdd("origin", urlToRepo, ".") if err != nil { log.Fatal(err) } @@ -99,5 +103,6 @@ func init() { projectCreateCmd.Flags().BoolVarP(&private, "private", "p", false, "make project private: visible only to project members") projectCreateCmd.Flags().BoolVar(&public, "public", false, "make project public: visible without any authentication") projectCreateCmd.Flags().BoolVar(&internal, "internal", false, "make project internal: visible to any authenticated user (default)") + projectCreateCmd.Flags().BoolVar(&useHTTP, "http", false, "use HTTP protocol instead of SSH") projectCmd.AddCommand(projectCreateCmd) } diff --git a/cmd/util.go b/cmd/util.go index 2d8e4224..d14628a3 100644 --- a/cmd/util.go +++ b/cmd/util.go @@ -239,3 +239,13 @@ func textToMarkdown(text string) string { func LabPersistentPreRun(cmd *cobra.Command, args []string) { flagConfig(cmd.Flags()) } + +// labURLToRepo returns the string representing the URL to a certain repo based +// on the protocol used +func labURLToRepo(project *gitlab.Project) string { + urlToRepo := project.SSHURLToRepo + if useHTTP { + urlToRepo = project.HTTPURLToRepo + } + return urlToRepo +} diff --git a/cmd/util_test.go b/cmd/util_test.go index 15c41a2f..1cbff344 100644 --- a/cmd/util_test.go +++ b/cmd/util_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + gitlab "github.com/xanzy/go-gitlab" ) func Test_textToMarkdown(t *testing.T) { @@ -273,3 +274,19 @@ func Test_parseArgsRemoteAndProject(t *testing.T) { }) } } + +func Test_labURLToRepo(t *testing.T) { + HTTPURL := "https://test" + SSHURL := "ssh://test" + project := gitlab.Project{ + HTTPURLToRepo: HTTPURL, + SSHURLToRepo: SSHURL, + } + + urlToRepo := labURLToRepo(&project) + assert.Equal(t, urlToRepo, SSHURL) + + useHTTP = true + urlToRepo = labURLToRepo(&project) + assert.Equal(t, urlToRepo, HTTPURL) +} diff --git a/internal/gitlab/gitlab.go b/internal/gitlab/gitlab.go index ce22ad40..5f02b5ab 100644 --- a/internal/gitlab/gitlab.go +++ b/internal/gitlab/gitlab.go @@ -210,8 +210,8 @@ func FindProject(project string) (*gitlab.Project, error) { return target, nil } -// Fork creates a user fork of a GitLab project -func Fork(project string) (string, error) { +// Fork creates a user fork of a GitLab project using the specified protocol +func Fork(project string, useHTTP bool) (string, error) { if !strings.Contains(project, "/") { return "", errors.New("remote must include namespace") } @@ -220,7 +220,11 @@ func Fork(project string) (string, error) { // See if a fork already exists target, err := FindProject(parts[1]) if err == nil { - return target.HTTPURLToRepo, nil + urlToRepo := target.SSHURLToRepo + if useHTTP { + urlToRepo = target.HTTPURLToRepo + } + return urlToRepo, nil } else if err != nil && err != ErrProjectNotFound { return "", err } @@ -234,8 +238,11 @@ func Fork(project string) (string, error) { if err != nil { return "", err } - - return fork.HTTPURLToRepo, nil + urlToRepo := fork.SSHURLToRepo + if useHTTP { + urlToRepo = fork.HTTPURLToRepo + } + return urlToRepo, nil } // MRCreate opens a merge request on GitLab