fix(config): use XDG_CONFIG_HOME for config path instead of dirs::config_dir()#801
fix(config): use XDG_CONFIG_HOME for config path instead of dirs::config_dir()#801
Conversation
…nfig path Aligns with mise's approach — always use ~/.config/hk/ regardless of platform, instead of ~/Library/Application Support/hk/ on macOS.
Greptile SummaryThis PR replaces
Confidence Score: 4/5Safe to merge for new users; existing macOS users with a global config at the old platform path will silently lose that config without a migration hint. The code change itself is correct and clean. The concern is a present behavioral regression: macOS users who already have config at ~/Library/Application Support/hk/config.pkl will see it silently ignored. Adding a fallback check (with a deprecation warning pointing to the new path) before merging would make this fully safe. src/env.rs and src/config.rs — the config resolution logic in config.rs should mirror the existing .hkrc.pkl migration pattern for the old macOS platform path. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Resolve HK_CONFIG_DIR] --> B{HK_CONFIG_DIR set?}
B -- yes --> C[Use $HK_CONFIG_DIR]
B -- no --> D{XDG_CONFIG_HOME set?}
D -- yes --> E[Use $XDG_CONFIG_HOME/hk]
D -- no --> F[Use ~/.config/hk]
subgraph Before
G[dirs::config_dir]
G -- macOS --> H[~/Library/Application Support/hk]
G -- Linux --> I[~/.config/hk]
G -- Windows --> J[AppData/Roaming/hk]
end
subgraph After this PR
C
E
F
end
Reviews (1): Last reviewed commit: "fix(config): use XDG_CONFIG_HOME instead..." | Re-trigger Greptile |
| pub static XDG_CONFIG_HOME: LazyLock<PathBuf> = | ||
| LazyLock::new(|| var_path("XDG_CONFIG_HOME").unwrap_or_else(|| HOME_DIR.join(".config"))); | ||
| pub static HK_CONFIG_DIR: LazyLock<PathBuf> = | ||
| LazyLock::new(|| var_path("HK_CONFIG_DIR").unwrap_or_else(|| XDG_CONFIG_HOME.join("hk"))); |
There was a problem hiding this comment.
This follows the same pattern as mise's MISE_CONFIG_DIR.
| pub static XDG_CONFIG_HOME: LazyLock<PathBuf> = | ||
| LazyLock::new(|| var_path("XDG_CONFIG_HOME").unwrap_or_else(|| HOME_DIR.join(".config"))); | ||
| pub static HK_CONFIG_DIR: LazyLock<PathBuf> = | ||
| LazyLock::new(|| var_path("HK_CONFIG_DIR").unwrap_or_else(|| XDG_CONFIG_HOME.join("hk"))); |
There was a problem hiding this comment.
Silent config breakage for existing macOS users
Before this change, HK_CONFIG_DIR on macOS resolved to ~/Library/Application Support/hk (via dirs::config_dir()). After this change it resolves to ~/.config/hk. Any macOS user who already has a global config.pkl at the old path will have their configuration silently ignored without any warning or migration hint. The existing deprecation/migration machinery in src/config.rs only covers .hkrc.pkl-style paths — there is no equivalent fallback that checks the old macOS platform path and nudges the user to move the file.
There was a problem hiding this comment.
The ~/Library/Application Support/hk/ path was never documented — the docs have always said ~/.config/hk/config.pkl. So in practice, no macOS user should have config at the old path.
There was a problem hiding this comment.
Code Review
This pull request refactors the configuration directory logic in src/env.rs by introducing XDG_CONFIG_HOME and basing HK_CONFIG_DIR on it. The review feedback suggests handling empty environment variables to comply with the XDG specification and warns that removing dirs::config_dir() creates breaking changes for macOS and Windows users who rely on platform-specific paths.
| pub static XDG_CONFIG_HOME: LazyLock<PathBuf> = | ||
| LazyLock::new(|| var_path("XDG_CONFIG_HOME").unwrap_or_else(|| HOME_DIR.join(".config"))); |
There was a problem hiding this comment.
According to the XDG Base Directory Specification, if $XDG_CONFIG_HOME is set but empty, it should fall back to the default ($HOME/.config). The current implementation treats an empty string as a valid path. Additionally, XDG_CONFIG_HOME is declared as pub but appears to be used only within this module; consider making it private if it's not intended for external use.
pub static XDG_CONFIG_HOME: LazyLock<PathBuf> = LazyLock::new(|| {
var_path("XDG_CONFIG_HOME")
.filter(|p| !p.as_os_str().is_empty())
.unwrap_or_else(|| HOME_DIR.join(".config"))
});| pub static HK_CONFIG_DIR: LazyLock<PathBuf> = | ||
| LazyLock::new(|| var_path("HK_CONFIG_DIR").unwrap_or_else(|| XDG_CONFIG_HOME.join("hk"))); |
There was a problem hiding this comment.
This change removes the use of dirs::config_dir(), which on macOS points to ~/Library/Application Support/hk and on Windows to AppData\Roaming\hk. This is a breaking change for users on these platforms who have existing global configurations. Consider providing a fallback to the old path or a migration warning. Also, applying a filter for empty strings ensures consistency with XDG-style environment variable handling.
pub static HK_CONFIG_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
var_path("HK_CONFIG_DIR")
.filter(|p| !p.as_os_str().is_empty())
.unwrap_or_else(|| XDG_CONFIG_HOME.join("hk"))
});### 🚀 Features - **(hook)** support per-worktree hooks via extensions.worktreeConfig by [@nkakouros](https://github.com/nkakouros) in [#789](#789) ### 🐛 Bug Fixes - **(config)** use XDG_CONFIG_HOME for config path instead of dirs::config_dir() by [@fukuchancat](https://github.com/fukuchancat) in [#801](#801) ### 📦️ Dependency Updates - update anthropics/claude-code-action digest to 0432df8 by [@renovate[bot]](https://github.com/renovate[bot]) in [#791](#791) - update rust crate indexmap to v2.13.1 by [@renovate[bot]](https://github.com/renovate[bot]) in [#792](#792) - update actions/configure-pages action to v6 by [@renovate[bot]](https://github.com/renovate[bot]) in [#795](#795) - update rust crate strum to 0.28 by [@renovate[bot]](https://github.com/renovate[bot]) in [#794](#794) - update actions/deploy-pages action to v5 by [@renovate[bot]](https://github.com/renovate[bot]) in [#796](#796) - update dependency globals to v17 by [@renovate[bot]](https://github.com/renovate[bot]) in [#797](#797) - update github artifact actions (major) by [@renovate[bot]](https://github.com/renovate[bot]) in [#798](#798) - update jdx/mise-action action to v4 by [@renovate[bot]](https://github.com/renovate[bot]) in [#799](#799) ### New Contributors - @fukuchancat made their first contribution in [#801](#801) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Primarily a version bump and documentation/lockfile updates; no functional Rust source changes are included in this diff. > > **Overview** > Publishes the `v1.41.0` release by bumping the crate/CLI version (`Cargo.toml`, `Cargo.lock`, `hk.usage.kdl`, generated CLI docs) and adding the `1.41.0` entry to `CHANGELOG.md`. > > Updates documentation and example Pkl snippets to reference the `v1.41.0` release artifacts, and refreshes `Cargo.lock` with dependency patch/minor updates (e.g., `tokio`, ICU crates, `signal-hook`, `semver`). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0c8dea7. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: mise-en-dev <[email protected]>
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [hk](https://github.com/jdx/hk) | minor | `1.40.0` → `1.41.0` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>jdx/hk (hk)</summary> ### [`v1.41.0`](https://github.com/jdx/hk/blob/HEAD/CHANGELOG.md#1410---2026-04-05) [Compare Source](jdx/hk@v1.40.0...v1.41.0) ##### 🚀 Features - **(hook)** support per-worktree hooks via extensions.worktreeConfig by [@​nkakouros](https://github.com/nkakouros) in [#​789](jdx/hk#789) ##### 🐛 Bug Fixes - **(builtins)** use workspace\_indicator for Go package-level analysis tools by [@​jdx](https://github.com/jdx) in [#​803](jdx/hk#803) - **(config)** use XDG\_CONFIG\_HOME for config path instead of dirs::config\_dir() by [@​fukuchancat](https://github.com/fukuchancat) in [#​801](jdx/hk#801) ##### 📦️ Dependency Updates - update anthropics/claude-code-action digest to [`0432df8`](jdx/hk@0432df8) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​791](jdx/hk#791) - update rust crate indexmap to v2.13.1 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​792](jdx/hk#792) - update actions/configure-pages action to v6 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​795](jdx/hk#795) - update rust crate strum to 0.28 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​794](jdx/hk#794) - update actions/deploy-pages action to v5 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​796](jdx/hk#796) - update dependency globals to v17 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​797](jdx/hk#797) - update github artifact actions (major) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​798](jdx/hk#798) - update jdx/mise-action action to v4 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​799](jdx/hk#799) ##### New Contributors - [@​fukuchancat](https://github.com/fukuchancat) made their first contribution in [#​801](jdx/hk#801) </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDQuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwNC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWlub3IiXX0=-->
Hello 🍣
I opened #800 to fix the docs showing
~/.config/hk/config.pklas the global config path, which doesn't match the actual path on macOS (~/Library/Application Support/hk/config.pklviadirs::config_dir()).Another option would be to align with mise's approach — use
$XDG_CONFIG_HOME(defaulting to~/.config) on all platforms instead ofdirs::config_dir(). This way~/.config/hk/config.pklworks everywhere and the docs are already correct.Not sure which approach makes more sense for hk — happy to defer to your judgment!