github.com/ForceCLI/config@v0.0.0-20230217143549-9149d42a3c99/config.go (about) 1 // Cross-platform configuration manager 2 package config 3 4 import ( 5 "fmt" 6 "github.com/mitchellh/go-homedir" 7 "io/ioutil" 8 "os" 9 "path" 10 "path/filepath" 11 "sort" 12 ) 13 14 type Config struct { 15 Base string 16 Entries map[string]ConfigEntry 17 } 18 19 type ConfigEntry struct { 20 Key string 21 Value string 22 } 23 24 // Create a new Config manager 25 func NewConfig(base string) (config *Config) { 26 config = &Config{} 27 config.Base = base 28 config.Entries = make(map[string]ConfigEntry) 29 return 30 } 31 32 // List keys for a given config 33 func (c *Config) List(name string) (keys []string, err error) { 34 configDir, err := c.configDirectory() 35 if err != nil { 36 return 37 } 38 dir := path.Join(configDir, name) 39 files, err := ioutil.ReadDir(dir) 40 if err != nil { 41 return 42 } 43 for _, file := range files { 44 keys = append(keys, file.Name()) 45 } 46 sort.Strings(keys) 47 return 48 } 49 50 // Save a key/value pair for a config 51 func (c *Config) Save(name, key, value string) (err error) { 52 return c.SaveGlobal(name, key, value) 53 } 54 55 func (c *Config) SaveGlobal(name, key, value string) (err error) { 56 dir, err := c.configDirectory() 57 if err != nil { 58 return 59 } 60 filename := path.Join(dir, name, key) 61 err = c.writeFile(filename, value) 62 return 63 } 64 65 func (c *Config) SaveLocal(name, key, value string) (err error) { 66 dir, err := c.localConfigDirectory() 67 if err != nil { 68 return 69 } 70 filename := path.Join(dir, name, key) 71 err = c.writeFile(filename, value) 72 return 73 } 74 75 // Load a value for a config key 76 func (c *Config) Load(name, key string) (body string, err error) { 77 return c.LoadGlobal(name, key) 78 } 79 80 func (c *Config) LoadGlobal(name, key string) (body string, err error) { 81 dir, err := c.configDirectory() 82 if err != nil { 83 return 84 } 85 filename := path.Join(dir, name, key) 86 body, err = c.readFile(filename) 87 return 88 } 89 90 // Load value from local config directory if it exists; otherwise from global 91 // config directory 92 func (c *Config) LoadLocalOrGlobal(name, key string) (body string, err error) { 93 dir, err := c.localConfigDirectory() 94 if err != nil { 95 return 96 } 97 filename := path.Join(dir, name, key) 98 body, err = c.readFile(filename) 99 if err != nil { 100 return c.LoadGlobal(name, key) 101 } 102 return 103 } 104 105 // Delete a config key/value pair 106 func (c *Config) Delete(name, key string) (err error) { 107 return c.DeleteGlobal(name, key) 108 } 109 110 func (c *Config) DeleteGlobal(name, key string) (err error) { 111 dir, err := c.configDirectory() 112 if err != nil { 113 return 114 } 115 filename := path.Join(dir, name, key) 116 err = os.Remove(filename) 117 return 118 } 119 120 // Delete a config key/value pair 121 func (c *Config) DeleteLocalOrGlobal(name, key string) (err error) { 122 dir, err := c.localConfigDirectory() 123 if err != nil { 124 return 125 } 126 filename := path.Join(dir, name, key) 127 err = os.Remove(filename) 128 if err != nil { 129 return c.DeleteGlobal(name, key) 130 } 131 return 132 } 133 134 func (c *Config) configDirectory() (configDir string, err error) { 135 home, err := c.homeDirectory() 136 if err != nil { 137 return 138 } 139 configDir = path.Join(home, fmt.Sprintf(".%s", c.Base)) 140 return 141 } 142 143 func (c *Config) localConfigDirectory() (configDir string, err error) { 144 cwd, err := os.Getwd() 145 if err != nil { 146 return 147 } 148 configDir = path.Join(cwd, fmt.Sprintf(".%s", c.Base)) 149 return 150 } 151 152 func (c *Config) writeFile(filename, body string) (err error) { 153 dir := filepath.Dir(filename) 154 if err = os.MkdirAll(dir, 0700); err != nil { 155 return err 156 } 157 err = ioutil.WriteFile(filename, []byte(body), 0600) 158 if err != nil { 159 return 160 } 161 return 162 } 163 164 func (c *Config) readFile(filename string) (body string, err error) { 165 data, err := ioutil.ReadFile(filename) 166 if err != nil { 167 return 168 } 169 body = string(data) 170 return 171 } 172 173 func (c *Config) homeDirectory() (string, error) { 174 return homedir.Dir() 175 }