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 }