github.com/cli/cli@v1.14.1-0.20210902173923-1af6a669e342/pkg/cmd/gist/clone/clone.go (about)

     1  package clone
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  
     7  	"github.com/MakeNowJust/heredoc"
     8  	"github.com/cli/cli/git"
     9  	"github.com/cli/cli/internal/config"
    10  	"github.com/cli/cli/pkg/cmdutil"
    11  	"github.com/cli/cli/pkg/iostreams"
    12  	"github.com/spf13/cobra"
    13  	"github.com/spf13/pflag"
    14  )
    15  
    16  type CloneOptions struct {
    17  	HttpClient func() (*http.Client, error)
    18  	Config     func() (config.Config, error)
    19  	IO         *iostreams.IOStreams
    20  
    21  	GitArgs   []string
    22  	Directory string
    23  	Gist      string
    24  }
    25  
    26  func NewCmdClone(f *cmdutil.Factory, runF func(*CloneOptions) error) *cobra.Command {
    27  	opts := &CloneOptions{
    28  		IO:         f.IOStreams,
    29  		HttpClient: f.HttpClient,
    30  		Config:     f.Config,
    31  	}
    32  
    33  	cmd := &cobra.Command{
    34  		DisableFlagsInUseLine: true,
    35  
    36  		Use:   "clone <gist> [<directory>] [-- <gitflags>...]",
    37  		Args:  cmdutil.MinimumArgs(1, "cannot clone: gist argument required"),
    38  		Short: "Clone a gist locally",
    39  		Long: heredoc.Doc(`
    40  			Clone a GitHub gist locally.
    41  
    42  			A gist can be supplied as argument in either of the following formats:
    43  			- by ID, e.g. 5b0e0062eb8e9654adad7bb1d81cc75f
    44  			- by URL, e.g. "https://gist.github.com/OWNER/5b0e0062eb8e9654adad7bb1d81cc75f"
    45  
    46  			Pass additional 'git clone' flags by listing them after '--'.
    47  		`),
    48  		RunE: func(cmd *cobra.Command, args []string) error {
    49  			opts.Gist = args[0]
    50  			opts.GitArgs = args[1:]
    51  
    52  			if runF != nil {
    53  				return runF(opts)
    54  			}
    55  
    56  			return cloneRun(opts)
    57  		},
    58  	}
    59  
    60  	cmd.SetFlagErrorFunc(func(cmd *cobra.Command, err error) error {
    61  		if err == pflag.ErrHelp {
    62  			return err
    63  		}
    64  		return &cmdutil.FlagError{Err: fmt.Errorf("%w\nSeparate git clone flags with '--'.", err)}
    65  	})
    66  
    67  	return cmd
    68  }
    69  
    70  func cloneRun(opts *CloneOptions) error {
    71  	gistURL := opts.Gist
    72  
    73  	if !git.IsURL(gistURL) {
    74  		cfg, err := opts.Config()
    75  		if err != nil {
    76  			return err
    77  		}
    78  		hostname, err := cfg.DefaultHost()
    79  		if err != nil {
    80  			return err
    81  		}
    82  		protocol, err := cfg.Get(hostname, "git_protocol")
    83  		if err != nil {
    84  			return err
    85  		}
    86  		gistURL = formatRemoteURL(hostname, gistURL, protocol)
    87  	}
    88  
    89  	_, err := git.RunClone(gistURL, opts.GitArgs)
    90  	if err != nil {
    91  		return err
    92  	}
    93  
    94  	return nil
    95  }
    96  
    97  func formatRemoteURL(hostname string, gistID string, protocol string) string {
    98  	if protocol == "ssh" {
    99  		return fmt.Sprintf("git@gist.%s:%s.git", hostname, gistID)
   100  	}
   101  
   102  	return fmt.Sprintf("https://gist.%s/%s.git", hostname, gistID)
   103  }