diff --git a/pkg/api/graphql_client.go b/pkg/api/graphql_client.go index 8c59531..515ce02 100644 --- a/pkg/api/graphql_client.go +++ b/pkg/api/graphql_client.go @@ -175,7 +175,7 @@ func graphQLEndpoint(host string) string { if IsEnterprise(host) { return fmt.Sprintf("https://%s/api/graphql", host) } - if strings.EqualFold(host, localhost) { + if strings.EqualFold(host, Localhost.String()) { return fmt.Sprintf("http://api.%s/graphql", host) } return fmt.Sprintf("https://api.%s/graphql", host) diff --git a/pkg/api/hosts.go b/pkg/api/hosts.go new file mode 100644 index 0000000..d389143 --- /dev/null +++ b/pkg/api/hosts.go @@ -0,0 +1,59 @@ +package api + +import ( + "fmt" + "strings" +) + +type Host string + +const ( + GitHub Host = "github.com" + Localhost Host = "github.localhost" + Tenancy Host = "ghe.com" + Garage Host = "garage.github.com" +) + +func (h Host) String() string { + return string(h) +} + +func ToHost(h string) Host { + if strings.HasSuffix(h, "."+Tenancy.String()) { + return Tenancy + } + + return Host(h) +} + +func isGarage(host string) bool { + return ToHost(host) == Garage +} + +func IsEnterprise(host string) bool { + typedHost := ToHost(host) + return typedHost != GitHub && typedHost != Tenancy && typedHost != Garage || typedHost != Localhost +} + +func IsTenancy(host string) bool { + return ToHost(host) == Tenancy +} + +func normalizeHostname(hostname string) string { + hostname = strings.ToLower(hostname) + if strings.HasSuffix(hostname, "."+GitHub.String()) { + return GitHub.String() + } + if strings.HasSuffix(hostname, "."+Localhost.String()) { + return Localhost.String() + } + // This has been copied over from the cli/cli NormalizeHostname function + // to ensure compatible behaviour but we don't fully understand when or + // why it would be useful here. We can't see what harm will come of + // duplicating the logic. + if before, found := strings.CutSuffix(hostname, "."+Tenancy.String()); found { + idx := strings.LastIndex(before, ".") + return fmt.Sprintf("%s.%s", before[idx+1:], Tenancy.String()) + } + return hostname +} diff --git a/pkg/api/hosts_test.go b/pkg/api/hosts_test.go new file mode 100644 index 0000000..f43b912 --- /dev/null +++ b/pkg/api/hosts_test.go @@ -0,0 +1,74 @@ +package api + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIsEnterprise(t *testing.T) { + tests := []struct { + name string + host string + wantOut bool + }{ + { + name: "github", + host: "github.com", + wantOut: false, + }, + { + name: "localhost", + host: "github.localhost", + wantOut: false, + }, + { + name: "enterprise", + host: "mygithub.com", + wantOut: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + out := IsEnterprise(tt.host) + assert.Equal(t, tt.wantOut, out) + }) + } +} + +func TestNormalizeHostname(t *testing.T) { + tests := []struct { + name string + host string + wantHost string + }{ + { + name: "github domain", + host: "test.github.com", + wantHost: "github.com", + }, + { + name: "capitalized", + host: "GitHub.com", + wantHost: "github.com", + }, + { + name: "localhost domain", + host: "test.github.localhost", + wantHost: "github.localhost", + }, + { + name: "enterprise domain", + host: "mygithub.com", + wantHost: "mygithub.com", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + normalized := normalizeHostname(tt.host) + assert.Equal(t, tt.wantHost, normalized) + }) + } +} diff --git a/pkg/api/http_client.go b/pkg/api/http_client.go index ea941a3..e5b9793 100644 --- a/pkg/api/http_client.go +++ b/pkg/api/http_client.go @@ -23,9 +23,7 @@ const ( accept = "Accept" authorization = "Authorization" contentType = "Content-Type" - github = "github.com" jsonContentType = "application/json; charset=utf-8" - localhost = "github.localhost" modulePath = "github.com/cli/go-gh" timeZone = "Time-Zone" userAgent = "User-Agent" @@ -130,40 +128,6 @@ func isSameDomain(requestHost, domain string) bool { return (requestHost == domain) || strings.HasSuffix(requestHost, "."+domain) } -func isGarage(host string) bool { - return strings.EqualFold(host, "garage.github.com") -} - -func IsEnterprise(host string) bool { - return host != github && host != localhost && !IsTenancy(host) -} - -// tenancyHost is the domain name of a tenancy GitHub instance. -const tenancyHost = "ghe.com" - -func IsTenancy(host string) bool { - return strings.HasSuffix(host, "."+tenancyHost) -} - -func normalizeHostname(hostname string) string { - hostname = strings.ToLower(hostname) - if strings.HasSuffix(hostname, "."+github) { - return github - } - if strings.HasSuffix(hostname, "."+localhost) { - return localhost - } - // This has been copied over from the cli/cli NormalizeHostname function - // to ensure compatible behaviour but we don't fully understand when or - // why it would be useful here. We can't see what harm will come of - // duplicating the logic. - if before, found := strings.CutSuffix(hostname, "."+tenancyHost); found { - idx := strings.LastIndex(before, ".") - return fmt.Sprintf("%s.%s", before[idx+1:], tenancyHost) - } - return hostname -} - type headerRoundTripper struct { headers map[string]string host string diff --git a/pkg/api/http_client_test.go b/pkg/api/http_client_test.go index ecc13a9..9fe0934 100644 --- a/pkg/api/http_client_test.go +++ b/pkg/api/http_client_test.go @@ -157,73 +157,6 @@ func TestNewHTTPClient(t *testing.T) { } } -func TestIsEnterprise(t *testing.T) { - tests := []struct { - name string - host string - wantOut bool - }{ - { - name: "github", - host: "github.com", - wantOut: false, - }, - { - name: "localhost", - host: "github.localhost", - wantOut: false, - }, - { - name: "enterprise", - host: "mygithub.com", - wantOut: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - out := IsEnterprise(tt.host) - assert.Equal(t, tt.wantOut, out) - }) - } -} - -func TestNormalizeHostname(t *testing.T) { - tests := []struct { - name string - host string - wantHost string - }{ - { - name: "github domain", - host: "test.github.com", - wantHost: "github.com", - }, - { - name: "capitalized", - host: "GitHub.com", - wantHost: "github.com", - }, - { - name: "localhost domain", - host: "test.github.localhost", - wantHost: "github.localhost", - }, - { - name: "enterprise domain", - host: "mygithub.com", - wantHost: "mygithub.com", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - normalized := normalizeHostname(tt.host) - assert.Equal(t, tt.wantHost, normalized) - }) - } -} - type tripper struct { roundTrip func(*http.Request) (*http.Response, error) } diff --git a/pkg/api/rest_client.go b/pkg/api/rest_client.go index b1cdbfd..dec7649 100644 --- a/pkg/api/rest_client.go +++ b/pkg/api/rest_client.go @@ -163,7 +163,7 @@ func restPrefix(hostname string) string { if IsEnterprise(hostname) { return fmt.Sprintf("https://%s/api/v3/", hostname) } - if strings.EqualFold(hostname, localhost) { + if strings.EqualFold(hostname, Localhost.String()) { return fmt.Sprintf("http://api.%s/", hostname) } return fmt.Sprintf("https://api.%s/", hostname)