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  }