* Add GH_HOST to hosts list if it has coresponding auth token * Keep default host at front of hosts list * Always add GH_HOST to hosts list
156 lines
3.7 KiB
Go
156 lines
3.7 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"sort"
|
|
"strconv"
|
|
|
|
"github.com/cli/cli/v2/internal/ghinstance"
|
|
"github.com/cli/cli/v2/pkg/set"
|
|
)
|
|
|
|
const (
|
|
GH_HOST = "GH_HOST"
|
|
GH_TOKEN = "GH_TOKEN"
|
|
GITHUB_TOKEN = "GITHUB_TOKEN"
|
|
GH_ENTERPRISE_TOKEN = "GH_ENTERPRISE_TOKEN"
|
|
GITHUB_ENTERPRISE_TOKEN = "GITHUB_ENTERPRISE_TOKEN"
|
|
CODESPACES = "CODESPACES"
|
|
)
|
|
|
|
type ReadOnlyEnvError struct {
|
|
Variable string
|
|
}
|
|
|
|
func (e *ReadOnlyEnvError) Error() string {
|
|
return fmt.Sprintf("read-only value in %s", e.Variable)
|
|
}
|
|
|
|
func InheritEnv(c Config) Config {
|
|
return &envConfig{Config: c}
|
|
}
|
|
|
|
type envConfig struct {
|
|
Config
|
|
}
|
|
|
|
func (c *envConfig) Hosts() ([]string, error) {
|
|
hosts, err := c.Config.Hosts()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
hostSet := set.NewStringSet()
|
|
hostSet.AddValues(hosts)
|
|
|
|
// If GH_HOST is set then add it to list.
|
|
if host := os.Getenv(GH_HOST); host != "" {
|
|
hostSet.Add(host)
|
|
}
|
|
|
|
// If there is a valid environment variable token for the
|
|
// default host then add default host to list.
|
|
if token, _ := AuthTokenFromEnv(ghinstance.Default()); token != "" {
|
|
hostSet.Add(ghinstance.Default())
|
|
}
|
|
|
|
s := hostSet.ToSlice()
|
|
// If default host is in list then move it to the front.
|
|
sort.SliceStable(s, func(i, j int) bool { return s[i] == ghinstance.Default() })
|
|
return s, nil
|
|
}
|
|
|
|
func (c *envConfig) DefaultHost() (string, error) {
|
|
val, _, err := c.DefaultHostWithSource()
|
|
return val, err
|
|
}
|
|
|
|
func (c *envConfig) DefaultHostWithSource() (string, string, error) {
|
|
if host := os.Getenv(GH_HOST); host != "" {
|
|
return host, GH_HOST, nil
|
|
}
|
|
return c.Config.DefaultHostWithSource()
|
|
}
|
|
|
|
func (c *envConfig) Get(hostname, key string) (string, error) {
|
|
val, _, err := c.GetWithSource(hostname, key)
|
|
return val, err
|
|
}
|
|
|
|
func (c *envConfig) GetWithSource(hostname, key string) (string, string, error) {
|
|
if hostname != "" && key == "oauth_token" {
|
|
if token, env := AuthTokenFromEnv(hostname); token != "" {
|
|
return token, env, nil
|
|
}
|
|
}
|
|
|
|
return c.Config.GetWithSource(hostname, key)
|
|
}
|
|
|
|
func (c *envConfig) GetOrDefault(hostname, key string) (val string, err error) {
|
|
val, _, err = c.GetOrDefaultWithSource(hostname, key)
|
|
return
|
|
}
|
|
|
|
func (c *envConfig) GetOrDefaultWithSource(hostname, key string) (val string, src string, err error) {
|
|
val, src, err = c.GetWithSource(hostname, key)
|
|
if err == nil && val == "" {
|
|
val = c.Default(key)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (c *envConfig) Default(key string) string {
|
|
return c.Config.Default(key)
|
|
}
|
|
|
|
func (c *envConfig) CheckWriteable(hostname, key string) error {
|
|
if hostname != "" && key == "oauth_token" {
|
|
if token, env := AuthTokenFromEnv(hostname); token != "" {
|
|
return &ReadOnlyEnvError{Variable: env}
|
|
}
|
|
}
|
|
|
|
return c.Config.CheckWriteable(hostname, key)
|
|
}
|
|
|
|
func AuthTokenFromEnv(hostname string) (string, string) {
|
|
if ghinstance.IsEnterprise(hostname) {
|
|
if token := os.Getenv(GH_ENTERPRISE_TOKEN); token != "" {
|
|
return token, GH_ENTERPRISE_TOKEN
|
|
}
|
|
|
|
if token := os.Getenv(GITHUB_ENTERPRISE_TOKEN); token != "" {
|
|
return token, GITHUB_ENTERPRISE_TOKEN
|
|
}
|
|
|
|
if isCodespaces, _ := strconv.ParseBool(os.Getenv(CODESPACES)); isCodespaces {
|
|
return os.Getenv(GITHUB_TOKEN), GITHUB_TOKEN
|
|
}
|
|
|
|
return "", ""
|
|
}
|
|
|
|
if token := os.Getenv(GH_TOKEN); token != "" {
|
|
return token, GH_TOKEN
|
|
}
|
|
|
|
return os.Getenv(GITHUB_TOKEN), GITHUB_TOKEN
|
|
}
|
|
|
|
func AuthTokenProvidedFromEnv() bool {
|
|
return os.Getenv(GH_ENTERPRISE_TOKEN) != "" ||
|
|
os.Getenv(GITHUB_ENTERPRISE_TOKEN) != "" ||
|
|
os.Getenv(GH_TOKEN) != "" ||
|
|
os.Getenv(GITHUB_TOKEN) != ""
|
|
}
|
|
|
|
func IsHostEnv(src string) bool {
|
|
return src == GH_HOST
|
|
}
|
|
|
|
func IsEnterpriseEnv(src string) bool {
|
|
return src == GH_ENTERPRISE_TOKEN || src == GITHUB_ENTERPRISE_TOKEN
|
|
}
|