github.com/zaquestion/lab@v0.25.1/cmd/clone.go (about) 1 package cmd 2 3 import ( 4 "strings" 5 "time" 6 7 "github.com/MakeNowJust/heredoc/v2" 8 retry "github.com/avast/retry-go" 9 "github.com/spf13/cobra" 10 "github.com/zaquestion/lab/internal/git" 11 "github.com/zaquestion/lab/internal/gitlab" 12 ) 13 14 // cloneCmd represents the clone command 15 var cloneCmd = &cobra.Command{ 16 Use: "clone", 17 Short: "GitLab aware clone repo command", 18 Long: heredoc.Doc(` 19 Clone a repository, similarly to 'git clone', but aware of GitLab 20 specific settings.`), 21 Example: heredoc.Doc(` 22 lab clone awesome-repo 23 lab clone company/awesome-repo --http 24 lab clone company/backend-team/awesome-repo`), 25 PersistentPreRun: labPersistentPreRun, 26 Run: func(cmd *cobra.Command, args []string) { 27 if len(args) == 0 { 28 log.Fatal("You must specify a repository to clone.") 29 } 30 31 useHTTP, err := cmd.Flags().GetBool("http") 32 if err != nil { 33 log.Fatal(err) 34 } 35 36 if useHTTP { 37 args = append(args, []string{"--http"}...) 38 } 39 40 project, err := gitlab.FindProject(args[0]) 41 if err == gitlab.ErrProjectNotFound { 42 err = git.New(append([]string{"clone"}, args...)...).Run() 43 if err != nil { 44 log.Fatal(err) 45 } 46 return 47 } else if err != nil { 48 log.Fatal(err) 49 } 50 path := labURLToRepo(project) 51 // #116 retry on the cases where we found a project but clone 52 // failed over ssh 53 err = retry.Do(func() error { 54 return git.New(append([]string{"clone", path}, args[1:]...)...).Run() 55 }, retry.Attempts(3), retry.Delay(time.Second)) 56 if err != nil { 57 log.Fatal(err) 58 } 59 60 // Clone project was a fork belonging to the user; user is 61 // treating forks as origin. Add upstream as remoted pointing 62 // to forked from repo 63 if project.ForkedFromProject != nil && 64 strings.Contains(project.PathWithNamespace, gitlab.User()) { 65 var dir string 66 if len(args) > 1 { 67 dir = args[1] 68 } else { 69 dir = project.Path 70 } 71 ffProject, err := gitlab.FindProject(project.ForkedFromProject.PathWithNamespace) 72 if err != nil { 73 log.Fatal(err) 74 } 75 urlToRepo := labURLToRepo(ffProject) 76 err = git.RemoteAdd("upstream", urlToRepo, "./"+dir) 77 if err != nil { 78 log.Fatal(err) 79 } 80 } 81 }, 82 } 83 84 func init() { 85 // useHTTP is defined in "project_create.go" 86 cloneCmd.Flags().BoolVar(&useHTTP, "http", false, "clone using HTTP protocol instead of SSH") 87 RootCmd.AddCommand(cloneCmd) 88 }