github.com/matthewdale/lab@v0.14.0/cmd/clone.go (about) 1 package cmd 2 3 import ( 4 "log" 5 "strings" 6 "time" 7 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 // NOTE: There is special handling for "clone" in cmd/root.go 16 var cloneCmd = &cobra.Command{ 17 Use: "clone", 18 Short: "GitLab repo aware clone command", 19 Long: `Clone supports these shorthands 20 - repo 21 - namespace/repo 22 - namespace/group/repo`, 23 Run: func(cmd *cobra.Command, args []string) { 24 project, err := gitlab.FindProject(args[0]) 25 if err == gitlab.ErrProjectNotFound { 26 err = git.New(append([]string{"clone"}, args...)...).Run() 27 if err != nil { 28 log.Fatal(err) 29 } 30 return 31 } else if err != nil { 32 log.Fatal(err) 33 } 34 path := project.SSHURLToRepo 35 // #116 retry on the cases where we found a project but clone 36 // failed over ssh 37 err = retry.Do(func() error { 38 return git.New(append([]string{"clone", path}, args[1:]...)...).Run() 39 }, retry.Attempts(3), retry.Delay(time.Second), retry.Units(time.Nanosecond)) 40 if err != nil { 41 log.Fatal(err) 42 } 43 44 // Clone project was a fork belonging to the user; user is 45 // treating forks as origin. Add upstream as remoted pointing 46 // to forked from repo 47 if project.ForkedFromProject != nil && 48 strings.Contains(project.PathWithNamespace, gitlab.User()) { 49 var dir string 50 if len(args) > 1 { 51 dir = args[1] 52 } else { 53 dir = project.Name 54 } 55 ffProject, err := gitlab.FindProject(project.ForkedFromProject.PathWithNamespace) 56 if err != nil { 57 log.Fatal(err) 58 } 59 err = git.RemoteAdd("upstream", ffProject.SSHURLToRepo, "./"+dir) 60 if err != nil { 61 log.Fatal(err) 62 } 63 } 64 }, 65 } 66 67 func init() { 68 RootCmd.AddCommand(cloneCmd) 69 }