github.com/cli/cli@v1.14.1-0.20210902173923-1af6a669e342/internal/config/config_type.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"gopkg.in/yaml.v3"
     7  )
     8  
     9  // This interface describes interacting with some persistent configuration for gh.
    10  type Config interface {
    11  	Get(string, string) (string, error)
    12  	GetWithSource(string, string) (string, string, error)
    13  	Set(string, string, string) error
    14  	UnsetHost(string)
    15  	Hosts() ([]string, error)
    16  	DefaultHost() (string, error)
    17  	DefaultHostWithSource() (string, string, error)
    18  	Aliases() (*AliasConfig, error)
    19  	CheckWriteable(string, string) error
    20  	Write() error
    21  }
    22  
    23  type ConfigOption struct {
    24  	Key           string
    25  	Description   string
    26  	DefaultValue  string
    27  	AllowedValues []string
    28  }
    29  
    30  var configOptions = []ConfigOption{
    31  	{
    32  		Key:           "git_protocol",
    33  		Description:   "the protocol to use for git clone and push operations",
    34  		DefaultValue:  "https",
    35  		AllowedValues: []string{"https", "ssh"},
    36  	},
    37  	{
    38  		Key:          "editor",
    39  		Description:  "the text editor program to use for authoring text",
    40  		DefaultValue: "",
    41  	},
    42  	{
    43  		Key:           "prompt",
    44  		Description:   "toggle interactive prompting in the terminal",
    45  		DefaultValue:  "enabled",
    46  		AllowedValues: []string{"enabled", "disabled"},
    47  	},
    48  	{
    49  		Key:          "pager",
    50  		Description:  "the terminal pager program to send standard output to",
    51  		DefaultValue: "",
    52  	},
    53  	{
    54  		Key:          "http_unix_socket",
    55  		Description:  "the path to a unix socket through which to make HTTP connection",
    56  		DefaultValue: "",
    57  	},
    58  	{
    59  		Key:          "browser",
    60  		Description:  "the web browser to use for opening URLs",
    61  		DefaultValue: "",
    62  	},
    63  }
    64  
    65  func ConfigOptions() []ConfigOption {
    66  	return configOptions
    67  }
    68  
    69  func ValidateKey(key string) error {
    70  	for _, configKey := range configOptions {
    71  		if key == configKey.Key {
    72  			return nil
    73  		}
    74  	}
    75  
    76  	return fmt.Errorf("invalid key")
    77  }
    78  
    79  type InvalidValueError struct {
    80  	ValidValues []string
    81  }
    82  
    83  func (e InvalidValueError) Error() string {
    84  	return "invalid value"
    85  }
    86  
    87  func ValidateValue(key, value string) error {
    88  	var validValues []string
    89  
    90  	for _, v := range configOptions {
    91  		if v.Key == key {
    92  			validValues = v.AllowedValues
    93  			break
    94  		}
    95  	}
    96  
    97  	if validValues == nil {
    98  		return nil
    99  	}
   100  
   101  	for _, v := range validValues {
   102  		if v == value {
   103  			return nil
   104  		}
   105  	}
   106  
   107  	return &InvalidValueError{ValidValues: validValues}
   108  }
   109  
   110  func NewConfig(root *yaml.Node) Config {
   111  	return &fileConfig{
   112  		ConfigMap:    ConfigMap{Root: root.Content[0]},
   113  		documentRoot: root,
   114  	}
   115  }
   116  
   117  // NewFromString initializes a Config from a yaml string
   118  func NewFromString(str string) Config {
   119  	root, err := parseConfigData([]byte(str))
   120  	if err != nil {
   121  		panic(err)
   122  	}
   123  	return NewConfig(root)
   124  }
   125  
   126  // NewBlankConfig initializes a config file pre-populated with comments and default values
   127  func NewBlankConfig() Config {
   128  	return NewConfig(NewBlankRoot())
   129  }
   130  
   131  func NewBlankRoot() *yaml.Node {
   132  	return &yaml.Node{
   133  		Kind: yaml.DocumentNode,
   134  		Content: []*yaml.Node{
   135  			{
   136  				Kind: yaml.MappingNode,
   137  				Content: []*yaml.Node{
   138  					{
   139  						HeadComment: "What protocol to use when performing git operations. Supported values: ssh, https",
   140  						Kind:        yaml.ScalarNode,
   141  						Value:       "git_protocol",
   142  					},
   143  					{
   144  						Kind:  yaml.ScalarNode,
   145  						Value: "https",
   146  					},
   147  					{
   148  						HeadComment: "What editor gh should run when creating issues, pull requests, etc. If blank, will refer to environment.",
   149  						Kind:        yaml.ScalarNode,
   150  						Value:       "editor",
   151  					},
   152  					{
   153  						Kind:  yaml.ScalarNode,
   154  						Value: "",
   155  					},
   156  					{
   157  						HeadComment: "When to interactively prompt. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled",
   158  						Kind:        yaml.ScalarNode,
   159  						Value:       "prompt",
   160  					},
   161  					{
   162  						Kind:  yaml.ScalarNode,
   163  						Value: "enabled",
   164  					},
   165  					{
   166  						HeadComment: "A pager program to send command output to, e.g. \"less\". Set the value to \"cat\" to disable the pager.",
   167  						Kind:        yaml.ScalarNode,
   168  						Value:       "pager",
   169  					},
   170  					{
   171  						Kind:  yaml.ScalarNode,
   172  						Value: "",
   173  					},
   174  					{
   175  						HeadComment: "Aliases allow you to create nicknames for gh commands",
   176  						Kind:        yaml.ScalarNode,
   177  						Value:       "aliases",
   178  					},
   179  					{
   180  						Kind: yaml.MappingNode,
   181  						Content: []*yaml.Node{
   182  							{
   183  								Kind:  yaml.ScalarNode,
   184  								Value: "co",
   185  							},
   186  							{
   187  								Kind:  yaml.ScalarNode,
   188  								Value: "pr checkout",
   189  							},
   190  						},
   191  					},
   192  					{
   193  						HeadComment: "The path to a unix socket through which send HTTP connections. If blank, HTTP traffic will be handled by net/http.DefaultTransport.",
   194  						Kind:        yaml.ScalarNode,
   195  						Value:       "http_unix_socket",
   196  					},
   197  					{
   198  						Kind:  yaml.ScalarNode,
   199  						Value: "",
   200  					},
   201  					{
   202  						HeadComment: "What web browser gh should use when opening URLs. If blank, will refer to environment.",
   203  						Kind:        yaml.ScalarNode,
   204  						Value:       "browser",
   205  					},
   206  					{
   207  						Kind:  yaml.ScalarNode,
   208  						Value: "",
   209  					},
   210  				},
   211  			},
   212  		},
   213  	}
   214  }