feat(config): move config file to XDG location #11

Merged
David merged 1 commit from feat/xdg-config-path into main 2026-05-13 22:40:29 +02:00
Owner

Summary

Moves the config file to the XDG Base Directory location and creates the app's subdirectory with restrictive permissions so it can safely hold the API token.

  • New default path: $XDG_CONFIG_HOME/youtrack-cli/config.yaml, with ~/.config/youtrack-cli/config.yaml as the fallback when XDG_CONFIG_HOME is unset or empty.
  • Old path ~/.youtrack-cli.yaml is no longer honored. Users with state at the old location need to re-run auth login; nothing is auto-migrated.
  • App subdirectory is created 0o700 only when missing; an existing ~/.config or $XDG_CONFIG_HOME keeps its current mode, so we don't surprise other tools by locking down a shared dir.
  • Config file is still written 0o600 (unchanged).
  • Override flag (--config <path>) and env var (YOUTRACK_CLI_CONFIG) still work as before.

This is a deliberate divergence from the Go CLI; CLAUDE.md and README.md are updated to call that out and to point newcomers at auth login as the path-creating entry point.

What changed

  • src/config.rs: Config::default_path() now composes xdg_config_home().join("youtrack-cli/config.yaml"). XDG resolution is factored into a pure resolve_xdg_config_home(xdg, home) -> Result<PathBuf> so it is unit-testable without touching process env. write_secure now calls ensure_app_dir which creates ancestors with the platform default mode and the immediate parent with 0o700.
  • src/cli.rs: --config help string updated to reflect the new default.
  • README.md: configuration section rewritten around auth login and the XDG path.
  • CLAUDE.md (project): project overview and repo-layout entries updated; the "drop-in replacement" language is replaced with a note explaining the deliberate XDG divergence.

Tests

  • xdg_set_wins_over_home, xdg_empty_falls_back_to_home_config, xdg_unset_falls_back_to_home_config, xdg_missing_home_errors: cover the four XDG resolution cases as a pure function.
  • save_creates_app_subdir_mode_700 (Unix only): saves into a non-existent <tmp>/youtrack-cli/config.yaml and asserts the parent dir ends up 0o700 and the file 0o600.
  • save_creates_ancestor_dirs_when_missing (Unix only): saves into a deeper non-existent path and asserts it lands on disk.
  • All existing tests still pass; cargo fmt --check, cargo clippy --all-targets -- -D warnings, cargo test --all-targets green locally.

Test plan

  • On a fresh box with no ~/.config/youtrack-cli, run youtrack-cli auth login --base-url https://<instance>. Confirm: the directory is created 0o700, the file is created 0o600, and ~/.youtrack-cli.yaml is NOT touched.
  • Set XDG_CONFIG_HOME=/tmp/xdg-test and re-run auth login. Confirm the file lands at /tmp/xdg-test/youtrack-cli/config.yaml and not under ~/.config/.
  • On a box where ~/.config exists already (typical), confirm its mode is unchanged after running auth login.
  • youtrack-cli config show reads from the new path without any extra flag.

Notes

  • ~/.youtrack-cli.yaml from a previous install is silently ignored. The "config file not found" error message already points users at auth login, so the recovery path is one command.
  • We considered a short-lived dotfile fallback for a smoother migration; user chose the clean break.
## Summary Moves the config file to the XDG Base Directory location and creates the app's subdirectory with restrictive permissions so it can safely hold the API token. - New default path: `$XDG_CONFIG_HOME/youtrack-cli/config.yaml`, with `~/.config/youtrack-cli/config.yaml` as the fallback when `XDG_CONFIG_HOME` is unset or empty. - Old path `~/.youtrack-cli.yaml` is no longer honored. Users with state at the old location need to re-run `auth login`; nothing is auto-migrated. - App subdirectory is created `0o700` only when missing; an existing `~/.config` or `$XDG_CONFIG_HOME` keeps its current mode, so we don't surprise other tools by locking down a shared dir. - Config file is still written `0o600` (unchanged). - Override flag (`--config <path>`) and env var (`YOUTRACK_CLI_CONFIG`) still work as before. This is a deliberate divergence from the Go CLI; CLAUDE.md and README.md are updated to call that out and to point newcomers at `auth login` as the path-creating entry point. ## What changed - `src/config.rs`: `Config::default_path()` now composes `xdg_config_home().join("youtrack-cli/config.yaml")`. XDG resolution is factored into a pure `resolve_xdg_config_home(xdg, home) -> Result<PathBuf>` so it is unit-testable without touching process env. `write_secure` now calls `ensure_app_dir` which creates ancestors with the platform default mode and the immediate parent with `0o700`. - `src/cli.rs`: `--config` help string updated to reflect the new default. - `README.md`: configuration section rewritten around `auth login` and the XDG path. - `CLAUDE.md` (project): project overview and repo-layout entries updated; the "drop-in replacement" language is replaced with a note explaining the deliberate XDG divergence. ## Tests - `xdg_set_wins_over_home`, `xdg_empty_falls_back_to_home_config`, `xdg_unset_falls_back_to_home_config`, `xdg_missing_home_errors`: cover the four XDG resolution cases as a pure function. - `save_creates_app_subdir_mode_700` (Unix only): saves into a non-existent `<tmp>/youtrack-cli/config.yaml` and asserts the parent dir ends up `0o700` and the file `0o600`. - `save_creates_ancestor_dirs_when_missing` (Unix only): saves into a deeper non-existent path and asserts it lands on disk. - All existing tests still pass; `cargo fmt --check`, `cargo clippy --all-targets -- -D warnings`, `cargo test --all-targets` green locally. ## Test plan - [ ] On a fresh box with no `~/.config/youtrack-cli`, run `youtrack-cli auth login --base-url https://<instance>`. Confirm: the directory is created `0o700`, the file is created `0o600`, and `~/.youtrack-cli.yaml` is NOT touched. - [ ] Set `XDG_CONFIG_HOME=/tmp/xdg-test` and re-run `auth login`. Confirm the file lands at `/tmp/xdg-test/youtrack-cli/config.yaml` and not under `~/.config/`. - [ ] On a box where `~/.config` exists already (typical), confirm its mode is unchanged after running `auth login`. - [ ] `youtrack-cli config show` reads from the new path without any extra flag. ## Notes - `~/.youtrack-cli.yaml` from a previous install is silently ignored. The "config file not found" error message already points users at `auth login`, so the recovery path is one command. - We considered a short-lived dotfile fallback for a smoother migration; user chose the clean break.
feat(config): move config file to XDG location
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 7s
Create release / Create release from merged PR (pull_request) Has been skipped
4641a94f23
`Config::default_path()` now returns `$XDG_CONFIG_HOME/youtrack-cli/config.yaml`, falling back to `~/.config/youtrack-cli/config.yaml` when `XDG_CONFIG_HOME` is unset or empty. The Go CLI's `~/.youtrack-cli.yaml` is no longer read or written; the port now prioritizes the XDG Base Directory spec over byte-compatibility, which matches the project's broader stance now that the user has chosen standards over drop-in inheritance. On save, the app subdirectory is created `0o700` (so it can hold the API token without inheriting a permissive parent), the file is still written `0o600`. Ancestor directories like `~/.config` are created with the platform default mode so we don't lock down a shared location used by other tools. Unit tests cover XDG resolution (set, empty, unset, missing HOME) plus the directory-mode invariant on Unix. README and CLAUDE.md are updated to point at the new location and to call out the deliberate divergence from the Go CLI. Users carrying state in `~/.youtrack-cli.yaml` will need to re-run `auth login` to populate the XDG path; nothing is migrated automatically.
David merged commit 5cfadd681a into main 2026-05-13 22:40:29 +02:00
David deleted branch feat/xdg-config-path 2026-05-13 22:40:29 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pandoras-box/youtrack-cli!11
No description provided.