@@ -18,6 +18,7 @@ import (
1818type Config struct {
1919 APIURL string `mapstructure:"api_url" yaml:"api_url"`
2020 Analytics bool `mapstructure:"analytics" yaml:"analytics"`
21+ Color bool `mapstructure:"color" yaml:"color"`
2122 ConfigDir string `mapstructure:"config_dir" yaml:"-"`
2223 ConsoleURL string `mapstructure:"console_url" yaml:"console_url"`
2324 Debug bool `mapstructure:"debug" yaml:"debug"`
@@ -31,11 +32,13 @@ type Config struct {
3132 ServiceID string `mapstructure:"service_id" yaml:"service_id"`
3233 VersionCheckInterval time.Duration `mapstructure:"version_check_interval" yaml:"version_check_interval"`
3334 VersionCheckLastTime time.Time `mapstructure:"version_check_last_time" yaml:"version_check_last_time"`
35+ viper * viper.Viper `mapstructure:"-" yaml:"-"`
3436}
3537
3638type ConfigOutput struct {
3739 APIURL * string `mapstructure:"api_url" json:"api_url,omitempty" yaml:"api_url,omitempty"`
3840 Analytics * bool `mapstructure:"analytics" json:"analytics,omitempty" yaml:"analytics,omitempty"`
41+ Color * bool `mapstructure:"color" json:"color,omitempty" yaml:"color,omitempty"`
3942 ConfigDir * string `mapstructure:"config_dir" json:"config_dir,omitempty" yaml:"config_dir,omitempty"`
4043 ConsoleURL * string `mapstructure:"console_url" json:"console_url,omitempty" yaml:"console_url,omitempty"`
4144 Debug * bool `mapstructure:"debug" json:"debug,omitempty" yaml:"debug,omitempty"`
@@ -52,33 +55,35 @@ type ConfigOutput struct {
5255}
5356
5457const (
58+ ConfigFileName = "config.yaml"
5559 DefaultAPIURL = "https://console.cloud.timescale.com/public/api/v1"
60+ DefaultAnalytics = true
61+ DefaultColor = true
5662 DefaultConsoleURL = "https://console.cloud.timescale.com"
57- DefaultGatewayURL = "https://console.cloud.timescale.com/api"
63+ DefaultDebug = false
5864 DefaultDocsMCP = true
5965 DefaultDocsMCPURL = "https://mcp.tigerdata.com/docs"
66+ DefaultGatewayURL = "https://console.cloud.timescale.com/api"
6067 DefaultOutput = "table"
61- DefaultAnalytics = true
6268 DefaultPasswordStorage = "keyring"
63- DefaultDebug = false
6469 DefaultReleasesURL = "https://cli.tigerdata.com"
6570 DefaultVersionCheckInterval = 24 * time .Hour
66- ConfigFileName = "config.yaml"
6771)
6872
6973var defaultValues = map [string ]any {
74+ "analytics" : DefaultAnalytics ,
7075 "api_url" : DefaultAPIURL ,
76+ "color" : DefaultColor ,
7177 "console_url" : DefaultConsoleURL ,
72- "gateway_url " : DefaultGatewayURL ,
78+ "debug " : DefaultDebug ,
7379 "docs_mcp" : DefaultDocsMCP ,
7480 "docs_mcp_url" : DefaultDocsMCPURL ,
75- "project_id" : "" ,
76- "service_id" : "" ,
81+ "gateway_url" : DefaultGatewayURL ,
7782 "output" : DefaultOutput ,
78- "analytics" : DefaultAnalytics ,
7983 "password_storage" : DefaultPasswordStorage ,
80- "debug " : DefaultDebug ,
84+ "project_id " : "" ,
8185 "releases_url" : DefaultReleasesURL ,
86+ "service_id" : "" ,
8287 "version_check_interval" : DefaultVersionCheckInterval ,
8388 "version_check_last_time" : time.Time {},
8489}
@@ -125,6 +130,7 @@ func SetupViper(configDir string) error {
125130func FromViper (v * viper.Viper ) (* Config , error ) {
126131 cfg := & Config {
127132 ConfigDir : filepath .Dir (v .ConfigFileUsed ()),
133+ viper : v ,
128134 }
129135
130136 if err := v .Unmarshal (cfg ); err != nil {
@@ -213,7 +219,7 @@ func UseTestConfig(configDir string, values map[string]any) (*Config, error) {
213219
214220func (c * Config ) Set (key , value string ) error {
215221 // Validate and update the field
216- validated , err := c .updateField (key , value )
222+ validated , err := c .UpdateField (key , value )
217223 if err != nil {
218224 return err
219225 }
@@ -244,10 +250,10 @@ func setBool(key, val string) (bool, error) {
244250 return b , nil
245251}
246252
247- // updateField updates the field in the Config struct corresponding to the given key.
253+ // UpdateField updates the field in the Config struct corresponding to the given key.
248254// It accepts either a string (from user input) or a typed value (string/bool from defaults).
249255// The function validates the value and updates both the struct field and viper state.
250- func (c * Config ) updateField (key string , value any ) (any , error ) {
256+ func (c * Config ) UpdateField (key string , value any ) (any , error ) {
251257 var validated any
252258
253259 switch key {
@@ -315,6 +321,22 @@ func (c *Config) updateField(key string, value any) (any, error) {
315321 c .ServiceID = s
316322 validated = s
317323
324+ case "color" :
325+ switch v := value .(type ) {
326+ case bool :
327+ c .Color = v
328+ validated = v
329+ case string :
330+ b , err := setBool ("color" , v )
331+ if err != nil {
332+ return nil , err
333+ }
334+ c .Color = b
335+ validated = b
336+ default :
337+ return nil , fmt .Errorf ("color must be string or bool, got %T" , value )
338+ }
339+
318340 case "output" :
319341 s , ok := value .(string )
320342 if ! ok {
@@ -433,7 +455,11 @@ func (c *Config) updateField(key string, value any) (any, error) {
433455 return nil , fmt .Errorf ("unknown configuration key: %s" , key )
434456 }
435457
436- viper .Set (key , validated )
458+ if c .viper == nil {
459+ viper .Set (key , validated )
460+ } else {
461+ c .viper .Set (key , validated )
462+ }
437463 return validated , nil
438464}
439465
@@ -465,7 +491,7 @@ func (c *Config) Unset(key string) error {
465491
466492 // Apply the default to the current global viper state
467493 if def , ok := defaultValues [key ]; ok {
468- if _ , err := c .updateField (key , def ); err != nil {
494+ if _ , err := c .UpdateField (key , def ); err != nil {
469495 return err
470496 }
471497 }
@@ -497,7 +523,7 @@ func (c *Config) Reset() error {
497523 if key == "project_id" {
498524 continue
499525 }
500- if _ , err := c .updateField (key , value ); err != nil {
526+ if _ , err := c .UpdateField (key , value ); err != nil {
501527 return err
502528 }
503529 }
0 commit comments