diff --git a/context/context.go b/context/context.go index 68695ddcf..85af0d8f9 100644 --- a/context/context.go +++ b/context/context.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/github/gh-cli/git" + "github.com/github/gh-cli/github" ) // GetToken returns the authentication token as stored in the config file for the user running gh-cli @@ -27,7 +28,7 @@ func GetToken() (string, error) { } func CurrentUsername() (string, error) { - host, err := CurrentConfig().DefaultHost() + host, err := github.CurrentConfig().DefaultHost() if err != nil { return "", nil } @@ -42,7 +43,3 @@ func CurrentBranch() (string, error) { return strings.Replace(currentBranch, "refs/heads/", "", 1), nil } - -func GitHubHostname() string { - return "github.com" -} diff --git a/context/ghrepo.go b/context/ghrepo.go index bfb8b8f84..5ea9a45a6 100644 --- a/context/ghrepo.go +++ b/context/ghrepo.go @@ -5,6 +5,8 @@ import ( "net/url" "os" "strings" + + "github.com/github/gh-cli/github" ) type GitHubRepository struct { @@ -19,7 +21,7 @@ func CurrentGitHubRepository() (*GitHubRepository, error) { var repoURL *url.URL var err error if repoFromEnv := os.Getenv("GH_REPO"); repoFromEnv != "" { - repoURL, err = url.Parse(fmt.Sprintf("https://%s/%s.git", GitHubHostname(), repoFromEnv)) + repoURL, err = url.Parse(fmt.Sprintf("https://github.com/%s.git", repoFromEnv)) if err != nil { return nil, err } @@ -33,7 +35,7 @@ func CurrentGitHubRepository() (*GitHubRepository, error) { } urlError := fmt.Errorf("invalid GitHub URL: %s", repoURL) - if repoURL.Host != GitHubHostname() && repoURL.Host != fmt.Sprintf("ssh.%s", GitHubHostname()) { + if !github.KnownGitHubHostsInclude(repoURL.Host) { return nil, urlError } @@ -62,17 +64,17 @@ func CurrentGitHubRepository() (*GitHubRepository, error) { } if host == "" { - host = GitHubHostname() + host = github.DefaultGitHubHost() } if host == "ssh.github.com" { - host = GitHubHostname() + host = github.GitHubHost } if protocol != "http" && protocol != "https" { protocol = "" } if protocol == "" { - h := CurrentConfig().Find(host) + h := github.CurrentConfig().Find(host) if h != nil { protocol = h.Protocol } @@ -82,7 +84,7 @@ func CurrentGitHubRepository() (*GitHubRepository, error) { } if owner == "" { - h := CurrentConfig().Find(host) + h := github.CurrentConfig().Find(host) if h != nil { owner = h.User } diff --git a/context/config.go b/github/config.go similarity index 98% rename from context/config.go rename to github/config.go index 5ff7fd186..420f56c19 100644 --- a/context/config.go +++ b/github/config.go @@ -1,4 +1,4 @@ -package context +package github import ( "bufio" @@ -41,7 +41,7 @@ func (c *Config) PromptForHost(host string) (h *Host, err error) { token := c.DetectToken() tokenFromEnv := token != "" - if host != GitHubHostname() { + if host != GitHubHost { if _, e := url.Parse("https://" + host); e != nil { err = fmt.Errorf("invalid hostname: %q", host) return @@ -338,7 +338,7 @@ func (c *Config) DefaultHost() (host *Host, err error) { // HACK: forces host to inherit GITHUB_TOKEN if applicable host, err = c.PromptForHost(host.Host) } else { - host, err = c.PromptForHost(GitHubHostname()) + host, err = c.PromptForHost(DefaultGitHubHost()) } return diff --git a/context/config_decoder.go b/github/config_decoder.go similarity index 98% rename from context/config_decoder.go rename to github/config_decoder.go index 8a703c0f8..7e467b761 100644 --- a/context/config_decoder.go +++ b/github/config_decoder.go @@ -1,4 +1,4 @@ -package context +package github import ( "io" diff --git a/context/config_encoder.go b/github/config_encoder.go similarity index 98% rename from context/config_encoder.go rename to github/config_encoder.go index 4b11f9b73..87609d38d 100644 --- a/context/config_encoder.go +++ b/github/config_encoder.go @@ -1,4 +1,4 @@ -package context +package github import ( "io" diff --git a/context/config_service.go b/github/config_service.go similarity index 97% rename from context/config_service.go rename to github/config_service.go index 121517e2c..3aaa6915f 100644 --- a/context/config_service.go +++ b/github/config_service.go @@ -1,4 +1,4 @@ -package context +package github import ( "os" diff --git a/github/hosts.go b/github/hosts.go new file mode 100644 index 000000000..a74d9810c --- /dev/null +++ b/github/hosts.go @@ -0,0 +1,64 @@ +package github + +import ( + "fmt" + "net/url" + "os" + "strings" + + "github.com/github/gh-cli/git" +) + +var ( + GitHubHostEnv = os.Getenv("GITHUB_HOST") + cachedHosts []string +) + +type GithubHostError struct { + url *url.URL +} + +func (e *GithubHostError) Error() string { + return fmt.Sprintf("Invalid GitHub URL: %s", e.url) +} + +func KnownGitHubHostsInclude(host string) bool { + for _, hh := range knownGitHubHosts() { + if hh == host { + return true + } + } + + return false +} + +func knownGitHubHosts() []string { + if cachedHosts != nil { + return cachedHosts + } + + hosts := []string{} + defaultHost := DefaultGitHubHost() + hosts = append(hosts, defaultHost) + hosts = append(hosts, "ssh.github.com") + + ghHosts, _ := git.ConfigAll("hub.host") + for _, ghHost := range ghHosts { + ghHost = strings.TrimSpace(ghHost) + if ghHost != "" { + hosts = append(hosts, ghHost) + } + } + + cachedHosts = hosts + return hosts +} + +func DefaultGitHubHost() string { + defaultHost := GitHubHostEnv + if defaultHost == "" { + defaultHost = GitHubHost + } + + return defaultHost +}