Resolve config, state and work dirs via XDG paths #4

Merged
schaefera merged 4 commits from worktree-xdg-paths into master 2026-09-20 08:26:53 +00:00
Collaborator

Why

First step toward pkgwatch managing itself from its own Forgejo releases: an installed /usr/bin/pkgwatch has no checkout to run from, so packages.d/, state/ and work/ can't be relative to the working directory.

What

  • New src/paths.rs: resolves the three directories per the XDG base-directory spec. The environment lookup is injectable, so the tests don't touch the real environment.

    What Default Override
    Package declarations ~/.config/pkgwatch/packages.d PKGWATCH_CONFIG_DIR (the dir containing packages.d)
    Last-published / pending versions ~/.local/state/pkgwatch PKGWATCH_STATE_DIR
    Downloads and build trees (safe to delete) ~/.cache/pkgwatch PKGWATCH_WORK_DIR

    Precedence per directory: override, then the XDG variable (XDG_CONFIG_HOME, XDG_STATE_HOME, XDG_CACHE_HOME), then the default under $HOME. Empty variables count as unset. Overrides are used verbatim (no pkgwatch/ suffix) and exist for dry runs against scratch dirs, like PKGWATCH_REPO_DIR does for the pacman repo. Relative XDG_* values are ignored, as the XDG spec requires, and a relative $HOME is an error; honoring either would bring back the cwd dependence this PR removes.

  • pipeline.rs: run_check and run_review use Paths instead of the hardcoded relative constants. A missing config dir now fails with a hint naming PKGWATCH_CONFIG_DIR and the SPEC's migration notes.

  • systemd/pkgwatch.service: drops WorkingDirectory, which is now redundant. The unit still runs the release binary from the checkout.

  • docs/SPEC.md: documents the paths table, precedence and migration steps.

This branch also merges in master after #3, with two trivial import-line conflicts.

Behaviour change

Plain cargo run in the repo no longer reads ./packages.d or ./state. The checkout's packages.d/ is now just the source to link from, not read on its own. With no config in place it fails with no package config at ~/.config/pkgwatch/packages.d (set PKGWATCH_CONFIG_DIR ...). The systemd timer will fail on every run until the XDG dirs are set up, and you'll get the failure notification.

Migration is deliberately deferred until the remaining self-hosting features are in. When it happens, from the old checkout:

mkdir -p ~/.config/pkgwatch ~/.local/state/pkgwatch
ln -s "$PWD/packages.d" ~/.config/pkgwatch/packages.d
cp state/* ~/.local/state/pkgwatch/

Skipping the state copy would make every package look new, including the pending scaleway-cli review. work/ is cache and can be dropped.

Testing

cargo fmt --check, cargo clippy --all-targets -- -D warnings and the complexity lint are clean. 99 tests pass, 8 of them new for paths (including relative-XDG and relative-HOME cases), in 20 of 20 runs. systemd-analyze verify --user is clean. I ran the built binary from / against scratch dirs, and review found a pending entry there. I did not run a full check, which would publish for real. A single-agent review found no blocking bugs; its relative-path finding and doc nits are addressed in the last commit.

Not changed

pipeline::custom_repo_dir still resolves PKGWATCH_REPO_DIR and HOME itself, and .gitignore still lists /state and /work; both are harmless and left for a later cleanup.

Next

Forgejo release source, release workflow and packages.d/pkgwatch.toml (items 1-3 of the self-hosting plan).

🤖 Generated with Claude Code

## Why First step toward pkgwatch managing itself from its own Forgejo releases: an installed `/usr/bin/pkgwatch` has no checkout to run from, so `packages.d/`, `state/` and `work/` can't be relative to the working directory. ## What - **New `src/paths.rs`**: resolves the three directories per the XDG base-directory spec. The environment lookup is injectable, so the tests don't touch the real environment. | What | Default | Override | |---|---|---| | Package declarations | `~/.config/pkgwatch/packages.d` | `PKGWATCH_CONFIG_DIR` (the dir *containing* `packages.d`) | | Last-published / pending versions | `~/.local/state/pkgwatch` | `PKGWATCH_STATE_DIR` | | Downloads and build trees (safe to delete) | `~/.cache/pkgwatch` | `PKGWATCH_WORK_DIR` | Precedence per directory: override, then the XDG variable (`XDG_CONFIG_HOME`, `XDG_STATE_HOME`, `XDG_CACHE_HOME`), then the default under `$HOME`. Empty variables count as unset. Overrides are used verbatim (no `pkgwatch/` suffix) and exist for dry runs against scratch dirs, like `PKGWATCH_REPO_DIR` does for the pacman repo. Relative `XDG_*` values are ignored, as the XDG spec requires, and a relative `$HOME` is an error; honoring either would bring back the cwd dependence this PR removes. - **`pipeline.rs`**: `run_check` and `run_review` use `Paths` instead of the hardcoded relative constants. A missing config dir now fails with a hint naming `PKGWATCH_CONFIG_DIR` and the SPEC's migration notes. - **`systemd/pkgwatch.service`**: drops `WorkingDirectory`, which is now redundant. The unit still runs the release binary from the checkout. - **`docs/SPEC.md`**: documents the paths table, precedence and migration steps. This branch also merges in master after #3, with two trivial import-line conflicts. ## Behaviour change Plain `cargo run` in the repo no longer reads `./packages.d` or `./state`. **The checkout's `packages.d/` is now just the source to link from, not read on its own.** With no config in place it fails with `no package config at ~/.config/pkgwatch/packages.d (set PKGWATCH_CONFIG_DIR ...)`. **The systemd timer will fail on every run until the XDG dirs are set up**, and you'll get the failure notification. Migration is deliberately deferred until the remaining self-hosting features are in. When it happens, from the old checkout: ```sh mkdir -p ~/.config/pkgwatch ~/.local/state/pkgwatch ln -s "$PWD/packages.d" ~/.config/pkgwatch/packages.d cp state/* ~/.local/state/pkgwatch/ ``` Skipping the state copy would make every package look new, including the pending scaleway-cli review. `work/` is cache and can be dropped. ## Testing `cargo fmt --check`, `cargo clippy --all-targets -- -D warnings` and the complexity lint are clean. 99 tests pass, 8 of them new for `paths` (including relative-XDG and relative-HOME cases), in 20 of 20 runs. `systemd-analyze verify --user` is clean. I ran the built binary from `/` against scratch dirs, and `review` found a pending entry there. I did not run a full check, which would publish for real. A single-agent review found no blocking bugs; its relative-path finding and doc nits are addressed in the last commit. ## Not changed `pipeline::custom_repo_dir` still resolves `PKGWATCH_REPO_DIR` and `HOME` itself, and `.gitignore` still lists `/state` and `/work`; both are harmless and left for a later cleanup. ## Next Forgejo release source, release workflow and `packages.d/pkgwatch.toml` (items 1-3 of the self-hosting plan). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude-bot added 3 commits 2026-09-20 08:06:13 +00:00
An installed pkgwatch has no checkout to run from, so packages.d/,
state/ and work/ can no longer be relative to the working directory.
New paths module resolves them per the XDG base-directory spec, with
PKGWATCH_{CONFIG,STATE,WORK}_DIR overrides for dry runs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Drop the now-unneeded WorkingDirectory from the service
All checks were successful
CI / build (pull_request) Successful in 50s
CI / test (pull_request) Successful in 2m21s
CI / audit (pull_request) Successful in 13s
CI / coverage (pull_request) Successful in 4m52s
6188f7f0b7
Paths no longer resolve relative to the cwd, so the unit's comment and
the SPEC's explanation of it were stale.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
schaefera added 1 commit 2026-09-20 08:19:15 +00:00
Apply review feedback on XDG paths
All checks were successful
CI / build (pull_request) Successful in 38s
CI / test (pull_request) Successful in 2m37s
CI / audit (pull_request) Successful in 12s
CI / coverage (pull_request) Successful in 5m13s
d0ab2525e4
Ignore relative XDG_* values and reject a relative HOME, per the XDG
spec; add a hint to the missing-config error; tighten docs and comments.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
schaefera scheduled this pull request to auto merge when all checks succeed 2026-09-20 08:22:56 +00:00
schaefera approved these changes 2026-09-20 08:26:51 +00:00
schaefera merged commit 9955610e09 into master 2026-09-20 08:26:53 +00:00
schaefera deleted branch worktree-xdg-paths 2026-09-20 08:27:02 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
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: schaefera/pkgwatch#4
No description provided.