8000 feat(load specific config file with --config) · jr-k/d4s@b0f8574 · GitHub
[go: up one dir, main page]

Skip to content

Commit b0f8574

Browse files
committed
feat(load specific config file with --config)
1 parent f1a82e4 commit b0f8574

2 files changed

Lines changed: 65 additions & 13 deletions

File tree

‎internal/config/config.go‎

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import (
1111
)
1212

1313
type Config struct {
14-
D4S D4SConfig `yaml:"d4s"`
14+
D4S D4SConfig `yaml:"d4s"`
15+
sourcePath string
1516
}
1617

1718
type D4SConfig struct {
@@ -179,11 +180,24 @@ func ensureConfigDirs() {
179180
_ = os.MkdirAll(filepath.Join(dir, "skins"), 0o755)
180181
}
181182

183+
func parse(data []byte, configPath string) (*Config, error) {
184+
cfg := DefaultConfig()
185+
if err := yaml.Unmarshal(data, cfg); err != nil {
186+
return nil, fmt.Errorf("parse config %q: %w", configPath, err)
187+
}
188+
189+
// Enforce minimum refresh rate
190+
if cfg.D4S.RefreshRate < 2.0 && cfg.D4S.RefreshRate > 0 {
191+
cfg.D4S.RefreshRate = 2.0
192+
}
193+
10BC8 194+
return cfg, nil
195+
}
196+
182197
// Load reads the config from $XDG_CONFIG_HOME/d4s/config.yaml.
183198
// If the file doesn't exist or can't be parsed, defaults are returned.
184199
func Load() *Config {
185200
cfg := DefaultConfig()
186-
187201
dir := configDir()
188202
if dir == "" {
189203
return cfg
@@ -202,27 +216,50 @@ func Load() *Config {
202216
}
203217
}
204218

205-
// Parse into a fresh config so we can detect which fields were explicitly set
206-
parsed := DefaultConfig()
207-
if err := yaml.Unmarshal(data, parsed); err != nil {
208-
fmt.Fprintf(os.Stderr, "d4s: warning: failed to parse %s: %v\n", configPath, err)
219+
loaded, err := parse(data, configPath)
220+
if err != nil {
221+
fmt.Fprintf(os.Stderr, "d4s: warning: %v\n", err)
209222
return cfg
210223
}
211224

212-
// Enforce minimum refresh rate
213-
if parsed.D4S.RefreshRate < 2.0 && parsed.D4S.RefreshRate > 0 {
214-
parsed.D4S.RefreshRate = 2.0
225+
return loaded
226+
}
227+
228+
// LoadFile reads exactly configPath and returns an error if it cannot be read or parsed.
229+
func LoadFile(configPath string) (*Config, error) {
230+
if configPath == "" {
231+
return nil, errors.New("config path is empty")
232+
}
233+
234+
data, err := os.ReadFile(configPath)
235+
if err != nil {
236+
return nil, fmt.Errorf("read config %q: %w", configPath, err)
215237
}
216238

217-
return parsed
239+
cfg, err := parse(data, configPath)
240+
if err != nil {
241+
return nil, err
242+
}
243+
cfg.sourcePath = configPath
244+
return cfg, nil
218245
}
219246

220-
// Save writes the config back to $XDG_CONFIG_HOME/d4s/config.yaml.
247+
// Save writes the config back to its explicit source file, or to the default
248+
// $XDG_CONFIG_HOME/d4s/config.yaml path when standard discovery was used.
221249
func Save(cfg *Config) error {
222250
if cfg == nil {
223251
return errors.New("nil config")
224252
}
225253

254+
configPath := cfg.sourcePath
255+
if configPath != "" {
256+
data, err := yaml.Marshal(cfg)
257+
if err != nil {
258+
return err
259+
}
260+
return os.WriteFile(configPath, data, 0o644)
261+
}
262+
226263
dir := configDir()
227264
if dir == "" {
228265
return errors.New("unable to determine config directory")
@@ -235,6 +272,6 @@ func Save(cfg *Config) error {
235272
return err
236273
}
237274

238-
configPath := filepath.Join(dir, "config.yaml")
275+
configPath = filepath.Join(dir, "config.yaml")
239276
return os.WriteFile(configPath, data, 0o644)
240277
}

‎main.go‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ func main() {
5858
flag.StringVar(&contextName, "context", "", "Docker context to use")
5959
flag.StringVar(&contextName, "c", "", "Docker context to use (shorthand)")
6060

61+
// Config flag
62+
var configPath string
63+
flag.StringVar(&configPath, "config", "", "Configuration file to use")
64+
6165
// Skin flag
6266
var skinName string
6367
flag.StringVar(&skinName, "skin", "", "Skin to use (overrides config)")
@@ -67,6 +71,7 @@ func main() {
6771
fmt.Fprintf(os.Stderr, "Usage: %s [options]\n\nOptions:\n", os.Args[0])
6872
fmt.Fprintf(os.Stderr, " -v, --version Print version and exit\n")
6973
fmt.Fprintf(os.Stderr, " -c, --context string Docker context to use\n")
74+
fmt.Fprintf(os.Stderr, " --config string Configuration file to use\n")
7075
fmt.Fprintf(os.Stderr, " -s, --skin string Skin to use (overrides config)\n")
7176
}
7277

@@ -105,7 +110,17 @@ func main() {
105110
return
106111
}
107112

108-
cfg := config.Load()
113+
var cfg *config.Config
114+
if configPath == "" {
115+
cfg = config.Load()
116+
} else {
117+
var err error
118+
cfg, err = config.LoadFile(configPath)
119+
if err != nil {
120+
fmt.Fprintf(os.Stderr, "d4s: configuration error: %v\n", err)
121+
os.Exit(1)
122+
}
123+
}
109124

110125
// CLI skin flag has max precedence
111126
if skinName != "" {

0 commit comments

Comments
 (0)
0