Adds a new command `gh auth setup-git [<hostname>]` that sets up git to use the GitHub CLI as a credential helper. The gist is that it runs these two git commands for each hostname the user is authenticated with. ``` git config --global --replace-all 'credential.https://github.com.helper' '' git config --global --add 'credential.https://github.com.helper' '!gh auth git-credential' ``` If a hostname flag is given, it'll setup GH CLI as a credential helper for only that hostname. If the user is not authenticated with any git hostnames, or the user is not authenticated with the hostname given as a flag, it'll print an error. Co-authored-by: Mislav Marohnić <mislav@github.com>
100 lines
2.1 KiB
Go
100 lines
2.1 KiB
Go
package setupgit
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/cli/cli/v2/internal/config"
|
|
"github.com/cli/cli/v2/pkg/cmd/auth/shared"
|
|
"github.com/cli/cli/v2/pkg/cmdutil"
|
|
"github.com/cli/cli/v2/pkg/iostreams"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
type gitConfigurator interface {
|
|
Setup(hostname, username, authToken string) error
|
|
}
|
|
|
|
type SetupGitOptions struct {
|
|
IO *iostreams.IOStreams
|
|
Config func() (config.Config, error)
|
|
Hostname string
|
|
gitConfigure gitConfigurator
|
|
}
|
|
|
|
func NewCmdSetupGit(f *cmdutil.Factory, runF func(*SetupGitOptions) error) *cobra.Command {
|
|
opts := &SetupGitOptions{
|
|
IO: f.IOStreams,
|
|
Config: f.Config,
|
|
}
|
|
|
|
cmd := &cobra.Command{
|
|
Short: "Configure git to use GitHub CLI as a credential helper",
|
|
Use: "setup-git",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
opts.gitConfigure = &shared.GitCredentialFlow{
|
|
Executable: f.Executable(),
|
|
}
|
|
|
|
if runF != nil {
|
|
return runF(opts)
|
|
}
|
|
return setupGitRun(opts)
|
|
},
|
|
}
|
|
|
|
cmd.Flags().StringVarP(&opts.Hostname, "hostname", "h", "", "The hostname to configure git for")
|
|
|
|
return cmd
|
|
}
|
|
|
|
func setupGitRun(opts *SetupGitOptions) error {
|
|
cfg, err := opts.Config()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
hostnames, err := cfg.Hosts()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
stderr := opts.IO.ErrOut
|
|
cs := opts.IO.ColorScheme()
|
|
|
|
if len(hostnames) == 0 {
|
|
fmt.Fprintf(
|
|
stderr,
|
|
"You are not logged into any GitHub hosts. Run %s to authenticate.\n",
|
|
cs.Bold("gh auth login"),
|
|
)
|
|
|
|
return cmdutil.SilentError
|
|
}
|
|
|
|
hostnamesToSetup := hostnames
|
|
|
|
if opts.Hostname != "" {
|
|
if !has(opts.Hostname, hostnames) {
|
|
return fmt.Errorf("You are not logged into the GitHub host %q\n", opts.Hostname)
|
|
}
|
|
hostnamesToSetup = []string{opts.Hostname}
|
|
}
|
|
|
|
for _, hostname := range hostnamesToSetup {
|
|
if err := opts.gitConfigure.Setup(hostname, "", ""); err != nil {
|
|
return fmt.Errorf("failed to set up git credential helper: %w", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func has(needle string, haystack []string) bool {
|
|
for _, s := range haystack {
|
|
if strings.EqualFold(s, needle) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|