internal/cfgfile/cfg.go (112 lines of code) (raw):

package cfgfile import ( "encoding/json" "fmt" "io" "os" "path/filepath" "github.com/tidwall/gjson" "github.com/tidwall/sjson" ) const CfgDirName = ".aztfexport" const CfgFileName = "config.json" type Configuration struct { InstallationId string `json:"installation_id"` TelemetryEnabled bool `json:"telemetry_enabled"` } func GetKey(key string) (interface{}, error) { homeDir, err := os.UserHomeDir() if err != nil { return nil, fmt.Errorf("retrieving the user's HOME directory: %v", err) } path := filepath.Join(homeDir, CfgDirName, CfgFileName) // #nosec G304 f, err := os.Open(path) if err != nil { return nil, fmt.Errorf("opening config: %v", err) } // #nosec G307 defer f.Close() b, err := io.ReadAll(f) if err != nil { return nil, fmt.Errorf("reading config: %v", err) } result := gjson.Get(string(b), key) if !result.Exists() { return "", fmt.Errorf("invalid key") } return result.Value(), nil } func SetKey(key, value string) error { homeDir, err := os.UserHomeDir() if err != nil { return fmt.Errorf("retrieving the user's HOME directory: %v", err) } path := filepath.Join(homeDir, CfgDirName, CfgFileName) // #nosec G304 b, err := os.ReadFile(path) if err != nil { return fmt.Errorf("reading config: %v", err) } var cfg Configuration if err := json.Unmarshal(b, &cfg); err != nil { return fmt.Errorf("unmarshalling the config: %v", err) } newCfg, err := updateConfiguration(cfg, key, value) if err != nil { return err } b, err = json.Marshal(*newCfg) if err != nil { return fmt.Errorf("marshalling the updated config: %v", err) } // #nosec G304 f, err := os.OpenFile(path, os.O_TRUNC|os.O_WRONLY, 0) if err != nil { return fmt.Errorf("open config for writing: %v", err) } // #nosec G307 defer f.Close() if _, err := f.Write(b); err != nil { return fmt.Errorf("writing config: %v", err) } return nil } func GetConfig() (*Configuration, error) { homeDir, err := os.UserHomeDir() if err != nil { return nil, fmt.Errorf("retrieving the user's HOME directory: %v", err) } path := filepath.Join(homeDir, CfgDirName, CfgFileName) // #nosec G304 f, err := os.Open(path) if err != nil { return nil, fmt.Errorf("opening config: %v", err) } // #nosec G307 defer f.Close() b, err := io.ReadAll(f) if err != nil { return nil, fmt.Errorf("reading config: %v", err) } var v Configuration if err := json.Unmarshal(b, &v); err != nil { return nil, err } return &v, nil } func updateConfiguration(old Configuration, k, v string) (*Configuration, error) { b, err := json.Marshal(old) if err != nil { return nil, fmt.Errorf("marshalling the old configuration: %v", err) } var vjson interface{} if err := json.Unmarshal([]byte(v), &vjson); err != nil { return nil, fmt.Errorf("unmarshalling the value: %v", err) } if !gjson.Get(string(b), k).Exists() { return nil, fmt.Errorf("invalid key %q", k) } updated, err := sjson.Set(string(b), k, vjson) if err != nil { return nil, fmt.Errorf("setting the value: %v", err) } var cfg Configuration if err := json.Unmarshal([]byte(updated), &cfg); err != nil { return nil, fmt.Errorf("unmarshalling the new configuration: %v", err) } return &cfg, nil }