summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-08-17 22:00:48 +0300
committerPaul Buetow <paul@buetow.org>2025-08-17 22:00:48 +0300
commit95ecff336b2f8315ad37daeb006d1639d1710ed0 (patch)
tree49e48ca590087e701ef85d6337a2a553dad0439b
parent562830b020aba76050c66f3115af7f6c88a87423 (diff)
refactor: Split up Load function in config.go
The Load function was too long, so it has been split up into smaller functions to improve readability and maintainability.
-rw-r--r--internal/appconfig/config.go109
1 files changed, 60 insertions, 49 deletions
diff --git a/internal/appconfig/config.go b/internal/appconfig/config.go
index 00b32bd..7076862 100644
--- a/internal/appconfig/config.go
+++ b/internal/appconfig/config.go
@@ -31,33 +31,23 @@ type App struct {
CopilotModel string `json:"copilot_model"`
}
-// Load reads configuration from a file and merges with defaults.
-// It respects the XDG Base Directory Specification.
-func Load(logger *log.Logger) App {
- cfg := App{
+func newDefaultConfig() App {
+ return App{
MaxTokens: 4000,
ContextMode: "always-full",
ContextWindowLines: 120,
MaxContextTokens: 4000,
LogPreviewLimit: 100,
-
- }
- if logger == nil {
- return cfg // Return defaults if no logger is provided (e.g. in tests)
- }
-
- configPath, err := getConfigPath()
- if err != nil {
- logger.Printf("%v", err)
- return cfg
}
+}
- f, err := os.Open(configPath)
+func loadFromFile(path string, logger *log.Logger) (*App, error) {
+ f, err := os.Open(path)
if err != nil {
if !os.IsNotExist(err) && logger != nil {
- logger.Printf("cannot open config file %s: %v", configPath, err)
+ logger.Printf("cannot open config file %s: %v", path, err)
}
- return cfg // Return defaults if file doesn't exist or can't be opened
+ return nil, err
}
defer f.Close()
@@ -65,54 +55,75 @@ func Load(logger *log.Logger) App {
var fileCfg App
if err := dec.Decode(&fileCfg); err != nil {
if logger != nil {
- logger.Printf("invalid config file %s: %v", configPath, err)
+ logger.Printf("invalid config file %s: %v", path, err)
}
- return cfg // Return defaults on decoding error
+ return nil, err
}
+ return &fileCfg, nil
+}
- // Merge: file overrides defaults when provided
- if fileCfg.MaxTokens > 0 {
- cfg.MaxTokens = fileCfg.MaxTokens
+func (a *App) mergeWith(other *App) {
+ if other.MaxTokens > 0 {
+ a.MaxTokens = other.MaxTokens
}
- if strings.TrimSpace(fileCfg.ContextMode) != "" {
- cfg.ContextMode = fileCfg.ContextMode
+ if strings.TrimSpace(other.ContextMode) != "" {
+ a.ContextMode = other.ContextMode
}
- if fileCfg.ContextWindowLines > 0 {
- cfg.ContextWindowLines = fileCfg.ContextWindowLines
+ if other.ContextWindowLines > 0 {
+ a.ContextWindowLines = other.ContextWindowLines
}
- if fileCfg.MaxContextTokens > 0 {
- cfg.MaxContextTokens = fileCfg.MaxContextTokens
+ if other.MaxContextTokens > 0 {
+ a.MaxContextTokens = other.MaxContextTokens
}
- if fileCfg.LogPreviewLimit >= 0 {
- cfg.LogPreviewLimit = fileCfg.LogPreviewLimit
+ if other.LogPreviewLimit >= 0 {
+ a.LogPreviewLimit = other.LogPreviewLimit
}
-
- if len(fileCfg.TriggerCharacters) > 0 {
- cfg.TriggerCharacters = slices.Clone(fileCfg.TriggerCharacters)
+ if len(other.TriggerCharacters) > 0 {
+ a.TriggerCharacters = slices.Clone(other.TriggerCharacters)
}
- if strings.TrimSpace(fileCfg.Provider) != "" {
- cfg.Provider = fileCfg.Provider
+ if strings.TrimSpace(other.Provider) != "" {
+ a.Provider = other.Provider
}
-
- // Provider-specific options
- if strings.TrimSpace(fileCfg.OpenAIBaseURL) != "" {
- cfg.OpenAIBaseURL = fileCfg.OpenAIBaseURL
+ if strings.TrimSpace(other.OpenAIBaseURL) != "" {
+ a.OpenAIBaseURL = other.OpenAIBaseURL
+ }
+ if strings.TrimSpace(other.OpenAIModel) != "" {
+ a.OpenAIModel = other.OpenAIModel
}
- if strings.TrimSpace(fileCfg.OpenAIModel) != "" {
- cfg.OpenAIModel = fileCfg.OpenAIModel
+ if strings.TrimSpace(other.OllamaBaseURL) != "" {
+ a.OllamaBaseURL = other.OllamaBaseURL
}
- if strings.TrimSpace(fileCfg.OllamaBaseURL) != "" {
- cfg.OllamaBaseURL = fileCfg.OllamaBaseURL
+ if strings.TrimSpace(other.OllamaModel) != "" {
+ a.OllamaModel = other.OllamaModel
}
- if strings.TrimSpace(fileCfg.OllamaModel) != "" {
- cfg.OllamaModel = fileCfg.OllamaModel
+ if strings.TrimSpace(other.CopilotBaseURL) != "" {
+ a.CopilotBaseURL = other.CopilotBaseURL
}
- if strings.TrimSpace(fileCfg.CopilotBaseURL) != "" {
- cfg.CopilotBaseURL = fileCfg.CopilotBaseURL
+ if strings.TrimSpace(other.CopilotModel) != "" {
+ a.CopilotModel = other.CopilotModel
}
- if strings.TrimSpace(fileCfg.CopilotModel) != "" {
- cfg.CopilotModel = fileCfg.CopilotModel
+}
+
+// Load reads configuration from a file and merges with defaults.
+// It respects the XDG Base Directory Specification.
+func Load(logger *log.Logger) App {
+ cfg := newDefaultConfig()
+ if logger == nil {
+ return cfg // Return defaults if no logger is provided (e.g. in tests)
+ }
+
+ configPath, err := getConfigPath()
+ if err != nil {
+ logger.Printf("%v", err)
+ return cfg
}
+
+ fileCfg, err := loadFromFile(configPath, logger)
+ if err != nil {
+ return cfg
+ }
+
+ cfg.mergeWith(fileCfg)
return cfg
}