github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/internal/config/config.go (about)

     1  package config
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  
     7  	ghAuth "github.com/cli/go-gh/pkg/auth"
     8  	ghConfig "github.com/cli/go-gh/pkg/config"
     9  )
    10  
    11  const (
    12  	hosts   = "hosts"
    13  	aliases = "aliases"
    14  )
    15  
    16  // This interface describes interacting with some persistent configuration for gh.
    17  //go:generate moq -rm -out config_mock.go . Config
    18  type Config interface {
    19  	AuthToken(string) (string, string)
    20  	Get(string, string) (string, error)
    21  	GetOrDefault(string, string) (string, error)
    22  	Set(string, string, string)
    23  	UnsetHost(string)
    24  	Hosts() []string
    25  	DefaultHost() (string, string)
    26  	Aliases() *AliasConfig
    27  	Write() error
    28  }
    29  
    30  func NewConfig() (Config, error) {
    31  	c, err := ghConfig.Read()
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	return &cfg{c}, nil
    36  }
    37  
    38  // Implements Config interface
    39  type cfg struct {
    40  	cfg *ghConfig.Config
    41  }
    42  
    43  func (c *cfg) AuthToken(hostname string) (string, string) {
    44  	return ghAuth.TokenForHost(hostname)
    45  }
    46  
    47  func (c *cfg) Get(hostname, key string) (string, error) {
    48  	if hostname != "" {
    49  		val, err := c.cfg.Get([]string{hosts, hostname, key})
    50  		if err == nil {
    51  			return val, err
    52  		}
    53  	}
    54  
    55  	return c.cfg.Get([]string{key})
    56  }
    57  
    58  func (c *cfg) GetOrDefault(hostname, key string) (string, error) {
    59  	var val string
    60  	var err error
    61  	if hostname != "" {
    62  		val, err = c.cfg.Get([]string{hosts, hostname, key})
    63  		if err == nil {
    64  			return val, err
    65  		}
    66  	}
    67  
    68  	val, err = c.cfg.Get([]string{key})
    69  	if err == nil {
    70  		return val, err
    71  	}
    72  
    73  	if defaultExists(key) {
    74  		return defaultFor(key), nil
    75  	}
    76  
    77  	return val, err
    78  }
    79  
    80  func (c *cfg) Set(hostname, key, value string) {
    81  	if hostname == "" {
    82  		c.cfg.Set([]string{key}, value)
    83  		return
    84  	}
    85  	c.cfg.Set([]string{hosts, hostname, key}, value)
    86  }
    87  
    88  func (c *cfg) UnsetHost(hostname string) {
    89  	if hostname == "" {
    90  		return
    91  	}
    92  	_ = c.cfg.Remove([]string{hosts, hostname})
    93  }
    94  
    95  func (c *cfg) Hosts() []string {
    96  	return ghAuth.KnownHosts()
    97  }
    98  
    99  func (c *cfg) DefaultHost() (string, string) {
   100  	return ghAuth.DefaultHost()
   101  }
   102  
   103  func (c *cfg) Aliases() *AliasConfig {
   104  	return &AliasConfig{cfg: c.cfg}
   105  }
   106  
   107  func (c *cfg) Write() error {
   108  	return ghConfig.Write(c.cfg)
   109  }
   110  
   111  func defaultFor(key string) string {
   112  	for _, co := range configOptions {
   113  		if co.Key == key {
   114  			return co.DefaultValue
   115  		}
   116  	}
   117  	return ""
   118  }
   119  
   120  func defaultExists(key string) bool {
   121  	for _, co := range configOptions {
   122  		if co.Key == key {
   123  			return true
   124  		}
   125  	}
   126  	return false
   127  }
   128  
   129  type AliasConfig struct {
   130  	cfg *ghConfig.Config
   131  }
   132  
   133  func (a *AliasConfig) Get(alias string) (string, error) {
   134  	return a.cfg.Get([]string{aliases, alias})
   135  }
   136  
   137  func (a *AliasConfig) Add(alias, expansion string) {
   138  	a.cfg.Set([]string{aliases, alias}, expansion)
   139  }
   140  
   141  func (a *AliasConfig) Delete(alias string) error {
   142  	return a.cfg.Remove([]string{aliases, alias})
   143  }
   144  
   145  func (a *AliasConfig) All() map[string]string {
   146  	out := map[string]string{}
   147  	keys, err := a.cfg.Keys([]string{aliases})
   148  	if err != nil {
   149  		return out
   150  	}
   151  	for _, key := range keys {
   152  		val, _ := a.cfg.Get([]string{aliases, key})
   153  		out[key] = val
   154  	}
   155  	return out
   156  }
   157  
   158  type ConfigOption struct {
   159  	Key           string
   160  	Description   string
   161  	DefaultValue  string
   162  	AllowedValues []string
   163  }
   164  
   165  var configOptions = []ConfigOption{
   166  	{
   167  		Key:           "git_protocol",
   168  		Description:   "the protocol to use for git clone and push operations",
   169  		DefaultValue:  "https",
   170  		AllowedValues: []string{"https", "ssh"},
   171  	},
   172  	{
   173  		Key:          "editor",
   174  		Description:  "the text editor program to use for authoring text",
   175  		DefaultValue: "",
   176  	},
   177  	{
   178  		Key:           "prompt",
   179  		Description:   "toggle interactive prompting in the terminal",
   180  		DefaultValue:  "enabled",
   181  		AllowedValues: []string{"enabled", "disabled"},
   182  	},
   183  	{
   184  		Key:          "pager",
   185  		Description:  "the terminal pager program to send standard output to",
   186  		DefaultValue: "",
   187  	},
   188  	{
   189  		Key:          "http_unix_socket",
   190  		Description:  "the path to a Unix socket through which to make an HTTP connection",
   191  		DefaultValue: "",
   192  	},
   193  	{
   194  		Key:          "browser",
   195  		Description:  "the web browser to use for opening URLs",
   196  		DefaultValue: "",
   197  	},
   198  }
   199  
   200  func ConfigOptions() []ConfigOption {
   201  	return configOptions
   202  }
   203  
   204  func HomeDirPath(subdir string) (string, error) {
   205  	homeDir, err := os.UserHomeDir()
   206  	if err != nil {
   207  		return "", err
   208  	}
   209  
   210  	newPath := filepath.Join(homeDir, subdir)
   211  	return newPath, nil
   212  }
   213  
   214  func StateDir() string {
   215  	return ghConfig.StateDir()
   216  }
   217  
   218  func DataDir() string {
   219  	return ghConfig.DataDir()
   220  }
   221  
   222  func ConfigDir() string {
   223  	return ghConfig.ConfigDir()
   224  }