github.com/knoebber/dotfile@v1.0.6/local/config.go (about) 1 package local 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os" 7 "path/filepath" 8 9 "github.com/knoebber/usererror" 10 "github.com/pkg/errors" 11 ) 12 13 // Config contains local user settings for dotfile. 14 type Config struct { 15 Remote string `json:"remote"` 16 Username string `json:"username"` 17 Token string `json:"token"` 18 } 19 20 func (c *Config) String() string { 21 return fmt.Sprintf("remote: %q\nusername: %q\ntoken: %q", 22 c.Remote, 23 c.Username, 24 c.Token, 25 ) 26 } 27 28 func createDefaultConfig(path string) ([]byte, error) { 29 var newCfg Config 30 31 bytes, err := json.MarshalIndent(newCfg, "", jsonIndent) 32 if err != nil { 33 return nil, errors.Wrap(err, "marshalling new user config file") 34 } 35 36 if err = os.WriteFile(path, bytes, 0644); err != nil { 37 return nil, errors.Wrap(err, "saving new user config file") 38 } 39 40 return bytes, nil 41 } 42 43 func configBytes(path string) ([]byte, error) { 44 if !exists(path) { 45 return createDefaultConfig(path) 46 } 47 48 bytes, err := os.ReadFile(path) 49 if err != nil { 50 return nil, errors.Wrap(err, "reading config bytes") 51 } 52 53 return bytes, nil 54 } 55 56 // DefaultConfigPath returns the default config file. 57 func DefaultConfigPath() (string, error) { 58 configDir, err := os.UserConfigDir() 59 if err != nil { 60 return "", err 61 } 62 dotfileDir := filepath.Join(configDir, "dotfile") 63 if !exists(dotfileDir) { 64 if err := os.MkdirAll(dotfileDir, 0755); err != nil { 65 return "", err 66 } 67 } 68 69 return filepath.Join(dotfileDir, "dotfile.json"), nil 70 } 71 72 // ReadConfig reads the user's config. 73 // Creates a default file when it doesn't yet exist. 74 func ReadConfig(path string) (*Config, error) { 75 cfg := new(Config) 76 77 bytes, err := configBytes(path) 78 if err != nil { 79 return nil, err 80 } 81 82 if err = json.Unmarshal(bytes, cfg); err != nil { 83 return nil, errors.Wrap(err, "unmarshalling config") 84 } 85 86 return cfg, nil 87 } 88 89 // SetConfig sets a value in the dotfile config json file. 90 func SetConfig(path, key, value string) error { 91 cfg := make(map[string]*string) 92 93 bytes, err := configBytes(path) 94 if err != nil { 95 return err 96 } 97 98 if err = json.Unmarshal(bytes, &cfg); err != nil { 99 return errors.Wrapf(err, "unmarshaling user config to map") 100 } 101 102 if _, ok := cfg[key]; !ok { 103 return usererror.Format("%q is not a valid config key", key) 104 } 105 106 cfg[key] = &value 107 108 bytes, err = json.MarshalIndent(cfg, "", jsonIndent) 109 if err != nil { 110 return errors.Wrap(err, "marshalling updated config map") 111 } 112 113 if err = os.WriteFile(path, bytes, 0644); err != nil { 114 return errors.Wrap(err, "saving updated config file") 115 } 116 117 return nil 118 }