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