1 // Package api is a set of types for interacting with the GitHub API. 2 package api 3 4 import ( 5 "fmt" 6 "io" 7 "net/http" 8 "time" 9 10 "github.com/cli/go-gh/v2/pkg/auth" 11 "github.com/cli/go-gh/v2/pkg/config" 12 ) 13 14 // ClientOptions holds available options to configure API clients. 15 type ClientOptions struct { 16 // AuthToken is the authorization token that will be used 17 // to authenticate against API endpoints. 18 AuthToken string 19 20 // CacheDir is the directory to use for cached API requests. 21 // Default is the same directory that gh uses for caching. 22 CacheDir string 23 24 // CacheTTL is the time that cached API requests are valid for. 25 // Default is 24 hours. 26 CacheTTL time.Duration 27 28 // EnableCache specifies if API requests will be cached or not. 29 // Default is no caching. 30 EnableCache bool 31 32 // Headers are the headers that will be sent with every API request. 33 // Default headers set are Accept, Content-Type, Time-Zone, and User-Agent. 34 // Default headers will be overridden by keys specified in Headers. 35 Headers map[string]string 36 37 // Host is the default host that API requests will be sent to. 38 Host string 39 40 // Log specifies a writer to write API request logs to. Default is to respect the GH_DEBUG environment 41 // variable, and no logging otherwise. 42 Log io.Writer 43 44 // LogIgnoreEnv disables respecting the GH_DEBUG environment variable. This can be useful in test mode 45 // or when the extension already offers its own controls for logging to the user. 46 LogIgnoreEnv bool 47 48 // LogColorize enables colorized logging to Log for display in a terminal. 49 // Default is no coloring. 50 LogColorize bool 51 52 // LogVerboseHTTP enables logging HTTP headers and bodies to Log. 53 // Default is only logging request URLs and response statuses. 54 LogVerboseHTTP bool 55 56 // SkipDefaultHeaders disables setting of the default headers. 57 SkipDefaultHeaders bool 58 59 // Timeout specifies a time limit for each API request. 60 // Default is no timeout. 61 Timeout time.Duration 62 63 // Transport specifies the mechanism by which individual API requests are made. 64 // If both Transport and UnixDomainSocket are specified then Transport takes 65 // precedence. Due to this behavior any value set for Transport needs to manually 66 // handle routing to UnixDomainSocket if necessary. Generally, setting Transport 67 // should be reserved for testing purposes. 68 // Default is http.DefaultTransport. 69 Transport http.RoundTripper 70 71 // UnixDomainSocket specifies the Unix domain socket address by which individual 72 // API requests will be routed. If specifed, this will form the base of the API 73 // request transport chain. 74 // Default is no socket address. 75 UnixDomainSocket string 76 } 77 78 func optionsNeedResolution(opts ClientOptions) bool { 79 if opts.Host == "" { 80 return true 81 } 82 if opts.AuthToken == "" { 83 return true 84 } 85 if opts.UnixDomainSocket == "" && opts.Transport == nil { 86 return true 87 } 88 return false 89 } 90 91 func resolveOptions(opts ClientOptions) (ClientOptions, error) { 92 cfg, _ := config.Read(nil) 93 if opts.Host == "" { 94 opts.Host, _ = auth.DefaultHost() 95 } 96 if opts.AuthToken == "" { 97 opts.AuthToken, _ = auth.TokenForHost(opts.Host) 98 if opts.AuthToken == "" { 99 return ClientOptions{}, fmt.Errorf("authentication token not found for host %s", opts.Host) 100 } 101 } 102 if opts.UnixDomainSocket == "" && cfg != nil { 103 opts.UnixDomainSocket, _ = cfg.Get([]string{"http_unix_socket"}) 104 } 105 return opts, nil 106 } 107