github.com/jenkins-x/jx/v2@v2.1.155/pkg/cmd/step/git/step_git_fork_and_clone.go (about)

     1  package git
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"github.com/jenkins-x/jx/v2/pkg/cmd/opts/step"
     8  
     9  	"github.com/jenkins-x/jx/v2/pkg/util"
    10  
    11  	"github.com/jenkins-x/jx/v2/pkg/cmd/helper"
    12  
    13  	"github.com/jenkins-x/jx-logging/pkg/log"
    14  
    15  	"github.com/pkg/errors"
    16  
    17  	"github.com/jenkins-x/jx/v2/pkg/cmd/opts"
    18  	"github.com/jenkins-x/jx/v2/pkg/cmd/templates"
    19  	"github.com/jenkins-x/jx/v2/pkg/gits"
    20  	"github.com/spf13/cobra"
    21  )
    22  
    23  // StepGitForkAndCloneOptions contains the command line flags
    24  type StepGitForkAndCloneOptions struct {
    25  	step.StepOptions
    26  	Dir         string
    27  	BaseRef     string
    28  	PrintOutDir bool
    29  	OutputDir   string
    30  }
    31  
    32  var (
    33  	// StepGitForkAndCloneLong command long description
    34  	StepGitForkAndCloneLong = templates.LongDesc(`
    35  		This pipeline step will clone a git repo, creating a fork if required. The fork is created if the owner of the 
    36  		repo is not the current git user (and that forking the git repo is allowed).
    37  
    38  `)
    39  	// StepGitForkAndCloneExample command example
    40  	StepGitForkAndCloneExample = templates.Examples(`
    41  		# Fork and clone the jx repo
    42  		jx step git fork-and-clone https://github.com/jenkins-x/jx.git
    43  
    44  		# Duplicate and clone the jx repo. This will create a new repo and mirror the contents of the source repo into,
    45  		# but it won't mark it as a fork in the git provider
    46  		jx step git fork-and-clone https://github.com/jenkins-x/jx.git --duplicate
    47  
    48  
    49  `)
    50  )
    51  
    52  // NewCmdStepGitForkAndClone create the 'step git envs' command
    53  func NewCmdStepGitForkAndClone(commonOpts *opts.CommonOptions) *cobra.Command {
    54  	options := StepGitForkAndCloneOptions{
    55  		StepOptions: step.StepOptions{
    56  			CommonOptions: commonOpts,
    57  		},
    58  	}
    59  	cmd := &cobra.Command{
    60  		Use:     "fork-and-clone",
    61  		Short:   "Forks and clones a git repo",
    62  		Long:    StepGitForkAndCloneLong,
    63  		Example: StepGitForkAndCloneExample,
    64  		Run: func(cmd *cobra.Command, args []string) {
    65  			options.Cmd = cmd
    66  			options.Args = args
    67  			err := options.Run()
    68  			helper.CheckErr(err)
    69  		},
    70  	}
    71  
    72  	cmd.Flags().StringVarP(&options.Dir, "dir", "", "", "The directory in which the git repo is checked out, by default the working directory")
    73  	cmd.Flags().StringVarP(&options.BaseRef, "base", "", "master", "The base ref to start from")
    74  	cmd.Flags().BoolVarP(&options.BatchMode, opts.OptionBatchMode, "b", false, "Enable batch mode")
    75  	cmd.Flags().BoolVarP(&options.PrintOutDir, "print-out-dir", "", false, "prints the directory the fork has been cloned to on stdout")
    76  	return cmd
    77  }
    78  
    79  // Run implements the command
    80  func (o *StepGitForkAndCloneOptions) Run() error {
    81  	if o.Dir == "" {
    82  		dir, err := os.Getwd()
    83  		if err != nil {
    84  			return err
    85  		}
    86  		o.Dir = dir
    87  	}
    88  	gitURL := ""
    89  	if len(o.Args) > 1 {
    90  		return errors.Errorf("Must specify exactly one git url but was %v", o.Args)
    91  	} else if len(o.Args) == 0 {
    92  		if os.Getenv("REPO_URL") != "" {
    93  			gitURL = os.Getenv("REPO_URL")
    94  		}
    95  	} else {
    96  		gitURL = o.Args[0]
    97  	}
    98  
    99  	if gitURL == "" {
   100  		return errors.Errorf("Must specify a git url on the CLI or using the environment variable REPO_URL")
   101  	}
   102  	provider, err := o.GitProviderForURL(gitURL, "git username")
   103  	if err != nil {
   104  		return errors.Wrapf(err, "getting git provider for %s", gitURL)
   105  	}
   106  	dir, baseRef, upstreamInfo, forkInfo, err := gits.ForkAndPullRepo(gitURL, o.Dir, o.BaseRef, "master", provider, o.Git(), "")
   107  	if err != nil {
   108  		return errors.Wrapf(err, "forking and pulling %s", gitURL)
   109  	}
   110  	o.OutDir = dir
   111  	if o.PrintOutDir {
   112  		// Output the directory so it can be used in a script
   113  		// Must use fmt.Print() as we need to write to stdout
   114  		fmt.Print(dir)
   115  	}
   116  	if forkInfo != nil {
   117  		log.Logger().Infof("Forked %s to %s, pulled it into %s and checked out %s", util.ColorInfo(upstreamInfo.HTMLURL), util.ColorInfo(forkInfo.HTMLURL), util.ColorInfo(dir), util.ColorInfo(baseRef))
   118  	} else {
   119  		log.Logger().Infof("Pulled %s (%s) into %s", upstreamInfo.URL, baseRef, dir)
   120  	}
   121  
   122  	return nil
   123  }