From 206aecfbfdc9adcb854f38d1addeb7db959032cd Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Wed, 1 Apr 2026 14:46:56 -0300 Subject: [PATCH] refactor: centralize user config path in a single func `home.Config()` (#2542) --- internal/commands/commands.go | 46 +++++++++-------------------------- internal/config/load.go | 14 +++-------- internal/fsext/ls.go | 12 ++------- internal/home/home.go | 9 +++++++ 4 files changed, 25 insertions(+), 56 deletions(-) diff --git a/internal/commands/commands.go b/internal/commands/commands.go index 65192c59e276cec5d3eabb2cc1250a437139797c..fe9d7e71606ebc15af1c5bdbddf85ab0b9a5c1fb 100644 --- a/internal/commands/commands.go +++ b/internal/commands/commands.go @@ -91,31 +91,20 @@ func LoadMCPPrompts() ([]MCPPrompt, error) { } func buildCommandSources(cfg *config.Config) []commandSource { - var sources []commandSource - - // XDG config directory - if dir := getXDGCommandsDir(); dir != "" { - sources = append(sources, commandSource{ - path: dir, + return []commandSource{ + { + path: filepath.Join(home.Config(), "crush", "commands"), prefix: userCommandPrefix, - }) - } - - // Home directory - if home := home.Dir(); home != "" { - sources = append(sources, commandSource{ - path: filepath.Join(home, ".crush", "commands"), + }, + { + path: filepath.Join(home.Dir(), ".crush", "commands"), prefix: userCommandPrefix, - }) + }, + { + path: filepath.Join(cfg.Options.DataDirectory, "commands"), + prefix: projectCommandPrefix, + }, } - - // Project directory - sources = append(sources, commandSource{ - path: filepath.Join(cfg.Options.DataDirectory, "commands"), - prefix: projectCommandPrefix, - }) - - return sources } func loadAll(sources []commandSource) ([]CustomCommand, error) { @@ -204,19 +193,6 @@ func buildCommandID(path, baseDir, prefix string) string { return prefix + strings.Join(parts, ":") } -func getXDGCommandsDir() string { - xdgHome := os.Getenv("XDG_CONFIG_HOME") - if xdgHome == "" { - if home := home.Dir(); home != "" { - xdgHome = filepath.Join(home, ".config") - } - } - if xdgHome != "" { - return filepath.Join(xdgHome, "crush", "commands") - } - return "" -} - func isMarkdownFile(name string) bool { return strings.HasSuffix(strings.ToLower(name), ".md") } diff --git a/internal/config/load.go b/internal/config/load.go index 6dd338e59e376f66a0d4471dd7b1e6e59ab76851..1040a20b5fb84f7aa265a49f370091f89532c41b 100644 --- a/internal/config/load.go +++ b/internal/config/load.go @@ -746,10 +746,7 @@ func GlobalConfig() string { if crushGlobal := os.Getenv("CRUSH_GLOBAL_CONFIG"); crushGlobal != "" { return filepath.Join(crushGlobal, fmt.Sprintf("%s.json", appName)) } - if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" { - return filepath.Join(xdgConfigHome, appName, fmt.Sprintf("%s.json", appName)) - } - return filepath.Join(home.Dir(), ".config", appName, fmt.Sprintf("%s.json", appName)) + return filepath.Join(home.Config(), appName, fmt.Sprintf("%s.json", appName)) } // GlobalConfigData returns the path to the main data directory for the application. @@ -799,14 +796,9 @@ func GlobalSkillsDirs() []string { return []string{crushSkills} } - configHome := cmp.Or( - os.Getenv("XDG_CONFIG_HOME"), - filepath.Join(home.Dir(), ".config"), - ) - paths := []string{ - filepath.Join(configHome, appName, "skills"), - filepath.Join(configHome, "agents", "skills"), + filepath.Join(home.Config(), appName, "skills"), + filepath.Join(home.Config(), "agents", "skills"), } // On Windows, also load from app data on top of `$HOME/.config/crush`. diff --git a/internal/fsext/ls.go b/internal/fsext/ls.go index 0d6653a147079316a37f9a9250b4d07dbd95d48c..5c0d6abb745fcc7951a22d844d918d2a3a21adf4 100644 --- a/internal/fsext/ls.go +++ b/internal/fsext/ls.go @@ -91,13 +91,9 @@ var gitGlobalIgnorePatterns = sync.OnceValue(func() []gitignore.Pattern { return nil } - configPath := cmp.Or( - os.Getenv("XDG_CONFIG_HOME"), - filepath.Join(home.Dir(), ".config"), - ) excludesFilePath := cmp.Or( cfg.Raw.Section("core").Options.Get("excludesfile"), - filepath.Join(configPath, "git", "ignore"), + filepath.Join(home.Config(), "git", "ignore"), ) excludesFilePath = home.Long(excludesFilePath) @@ -115,11 +111,7 @@ var gitGlobalIgnorePatterns = sync.OnceValue(func() []gitignore.Pattern { // crushGlobalIgnorePatterns returns patterns from the user's // ~/.config/crush/ignore file. var crushGlobalIgnorePatterns = sync.OnceValue(func() []gitignore.Pattern { - configPath := cmp.Or( - os.Getenv("XDG_CONFIG_HOME"), - filepath.Join(home.Dir(), ".config"), - ) - name := filepath.Join(configPath, "crush", "ignore") + name := filepath.Join(home.Config(), "crush", "ignore") bts, err := os.ReadFile(name) if err != nil { if !os.IsNotExist(err) { diff --git a/internal/home/home.go b/internal/home/home.go index 80fb1ea2e01630597c2547eaa8e4e55150ec6976..db5b2b6d44d4da645c1cc89e6e1ce42205763d4f 100644 --- a/internal/home/home.go +++ b/internal/home/home.go @@ -2,6 +2,7 @@ package home import ( + "cmp" "log/slog" "os" "path/filepath" @@ -21,6 +22,14 @@ func Dir() string { return homedir } +// Config returns the user config directory. +func Config() string { + return cmp.Or( + os.Getenv("XDG_CONFIG_HOME"), + filepath.Join(Dir(), ".config"), + ) +} + // Short replaces the actual home path from [Dir] with `~`. func Short(p string) string { if homedir == "" || !strings.HasPrefix(p, homedir) {