1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
package ghinstance
import (
"errors"
"fmt"
"strings"
)
// DefaultHostname is the domain name of the default GitHub instance.
const defaultHostname = "github.com"
// Localhost is the domain name of a local GitHub instance.
const localhost = "github.localhost"
// TenancyHost is the domain name of a tenancy GitHub instance.
const tenancyHost = "ghe.com"
// Default returns the host name of the default GitHub instance.
func Default() string {
return defaultHostname
}
// IsEnterprise reports whether a non-normalized host name looks like a GHE instance.
func IsEnterprise(h string) bool {
normalizedHostName := NormalizeHostname(h)
return normalizedHostName != defaultHostname && normalizedHostName != localhost
}
// IsTenancy reports whether a non-normalized host name looks like a tenancy instance.
func IsTenancy(h string) bool {
normalizedHostName := NormalizeHostname(h)
return strings.HasSuffix(normalizedHostName, "."+tenancyHost)
}
// TenantName extracts the tenant name from tenancy host name and
// reports whether it found the tenant name.
func TenantName(h string) (string, bool) {
normalizedHostName := NormalizeHostname(h)
return cutSuffix(normalizedHostName, "."+tenancyHost)
}
func isGarage(h string) bool {
return strings.EqualFold(h, "garage.github.com")
}
// NormalizeHostname returns the canonical host name of a GitHub instance.
func NormalizeHostname(h string) string {
hostname := strings.ToLower(h)
if strings.HasSuffix(hostname, "."+defaultHostname) {
return defaultHostname
}
if strings.HasSuffix(hostname, "."+localhost) {
return localhost
}
if before, found := cutSuffix(hostname, "."+tenancyHost); found {
idx := strings.LastIndex(before, ".")
return fmt.Sprintf("%s.%s", before[idx+1:], tenancyHost)
}
return hostname
}
func HostnameValidator(hostname string) error {
if len(strings.TrimSpace(hostname)) < 1 {
return errors.New("a value is required")
}
if strings.ContainsRune(hostname, '/') || strings.ContainsRune(hostname, ':') {
return errors.New("invalid hostname")
}
return nil
}
func GraphQLEndpoint(hostname string) string {
if isGarage(hostname) {
return fmt.Sprintf("https://%s/api/graphql", hostname)
}
if IsEnterprise(hostname) {
return fmt.Sprintf("https://%s/api/graphql", hostname)
}
if strings.EqualFold(hostname, localhost) {
return fmt.Sprintf("http://api.%s/graphql", hostname)
}
return fmt.Sprintf("https://api.%s/graphql", hostname)
}
func RESTPrefix(hostname string) string {
if isGarage(hostname) {
return fmt.Sprintf("https://%s/api/v3/", hostname)
}
if IsEnterprise(hostname) {
return fmt.Sprintf("https://%s/api/v3/", hostname)
}
if strings.EqualFold(hostname, localhost) {
return fmt.Sprintf("http://api.%s/", hostname)
}
return fmt.Sprintf("https://api.%s/", hostname)
}
func GistPrefix(hostname string) string {
prefix := "https://"
if strings.EqualFold(hostname, localhost) {
prefix = "http://"
}
return prefix + GistHost(hostname)
}
func GistHost(hostname string) string {
if isGarage(hostname) {
return fmt.Sprintf("%s/gist/", hostname)
}
if IsEnterprise(hostname) {
return fmt.Sprintf("%s/gist/", hostname)
}
if strings.EqualFold(hostname, localhost) {
return fmt.Sprintf("%s/gist/", hostname)
}
return fmt.Sprintf("gist.%s/", hostname)
}
func HostPrefix(hostname string) string {
if strings.EqualFold(hostname, localhost) {
return fmt.Sprintf("http://%s/", hostname)
}
return fmt.Sprintf("https://%s/", hostname)
}
// Backport strings.CutSuffix from Go 1.20.
func cutSuffix(s, suffix string) (string, bool) {
if !strings.HasSuffix(s, suffix) {
return s, false
}
return s[:len(s)-len(suffix)], true
}
|