Skip to content

feat(cli): honour XDG_CONFIG_HOME for the config directory - #2064

Merged
ChiragAgg5k merged 3 commits into
mainfrom
feat/cli-xdg-config
Oct 16, 2026
Merged

ChiragAgg5k merged 3 commits into
mainfrom
feat/cli-xdg-config

Conversation

@ChiragAgg5k

@ChiragAgg5k ChiragAgg5k commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

What

The CLI now resolves its config directory once, in config.GlobalDirectory, and every file it keeps there (prefs.json, update-check.json, the APNs apns/ session directory) follows that one answer.

State Directory used
~/.appwrite already exists ~/.appwrite (unchanged, no migration)
No ~/.appwrite, XDG_CONFIG_HOME set to an absolute path (created on first write if missing) $XDG_CONFIG_HOME/appwrite
No ~/.appwrite, XDG_CONFIG_HOME unset, empty or relative ~/.appwrite (unchanged default)

Relative values are ignored, as the XDG Base Directory spec requires. #131 also suggests falling back to ~/.appwrite when XDG_CONFIG_HOME does not exist; this deliberately does not, because apps are expected to create their XDG directories, and a fallback would send a user who points XDG_CONFIG_HOME at a new path to ~/.appwrite, which then wins on every later run. macOS and Windows defaults are unchanged; they only move when the user sets XDG_CONFIG_HOME themselves. The wasm build resolves the same way through the existing homeDir() shim.

The e2e harness now pins XDG_CONFIG_HOME inside its sandboxed HOME, and every unit test that sandboxes HOME without creating ~/.appwrite (the fan-out test, TestGenerateEndpointFallsBackToTheDefault and the completion tests' setHome) clears it, so an inherited value can never point a test at real credentials.

Reproduction

Empty scratch HOME and XDG_CONFIG_HOME, then:

HOME=$R/home XDG_CONFIG_HOME=$R/xdg appwrite client --endpoint https://cloud.appwrite.io/v1
find home xdg

Before (28.6.0), XDG is ignored:

home
home/.appwrite
home/.appwrite/prefs.json
home/.appwrite/update-check.json
xdg

After:

home
xdg
xdg/appwrite
xdg/appwrite/prefs.json
xdg/appwrite/update-check.json

After, with a pre-existing $HOME/.appwrite and XDG_CONFIG_HOME set, the existing directory is still used:

home
home/.appwrite
home/.appwrite/prefs.json
home/.appwrite/update-check.json
xdg

A signed-in command: scratch HOME (with ~/Library symlinked for the keychain), a copy of real prefs.json placed at $XDG_CONFIG_HOME/appwrite/prefs.json with .current pointing at a staging session, then appwrite whoami:

== before (28.6.0)
✗ Error: no active session. Run `appwrite login` to sign in
exit 1

== after
Name     : Chirag Aggarwal
Email    : <email>
Endpoint : https://fra.cloud.staging.appwrite.io/v1
exit 0

Tests

  • TestGlobalPathFollowsXDGConfigHome covers an existing ~/.appwrite winning over XDG, an absolute XDG_CONFIG_HOME, one that does not exist yet still being used, an unset one, and a relative one being ignored.
  • TestGenerateEndpointFallsBackToTheDefault failed before this PR's isolation fix when run with an inherited XDG_CONFIG_HOME whose appwrite/prefs.json has a custom endpoint (endpoint = "https://leaked.example/v1", want "https://cloud.appwrite.io/v1"). It now clears XDG_CONFIG_HOME, and the full go test ./... passes with that polluted value set.
  • TestGlobalWriteCreatesTheXDGDirectory checks that the first write lands under XDG_CONFIG_HOME and does not create ~/.appwrite.
  • Both fail on main (the absolute XDG case and the write test) and pass here.
  • php example.php cli, gofmt -l, go build ./..., go vet ./..., go test -race ./..., GOOS=js GOARCH=wasm go build -tags browser ., composer lint-twig and composer refactor:check all pass locally.

Fixes appwrite/sdk-for-cli#131

Closes #2066

Users who keep their home directory clean expect CLIs to store config under
XDG_CONFIG_HOME. The directory is now resolved once: an existing ~/.appwrite
keeps winning so current installs never lose their sessions, otherwise an
absolute XDG_CONFIG_HOME selects $XDG_CONFIG_HOME/appwrite, and ~/.appwrite
stays the default. The update-check cache and APNs session directory follow
the same resolution as prefs.json so nothing is split across two places.

The e2e harness pins XDG_CONFIG_HOME inside its sandboxed HOME so an
inherited value can never point it at real credentials.
@hansi-codes

hansi-codes Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

🟢 Tier S · Ready to merge

The CLI centralizes user-level state under a shared config directory, preserving an existing ~/.appwrite and otherwise selecting an absolute XDG_CONFIG_HOME for preferences and related state. The update-check cache and APNs sessions use the same location, and the tests and e2e harness isolate XDG configuration in temporary homes.

Latest changes: The newest commit removes the existence check for XDG_CONFIG_HOME and updates the config tests to verify that the missing directory is selected and created on first write.

Verdict New comments Fixed Still open
💬 Commented 0 0 0
📂 Walkthrough · 7
File Change
templates/cli/internal/app/install.go.twig Stores the update-check cache beside preferences using the shared config directory.
templates/cli/internal/cmd/completion_test.go Clears inherited XDG configuration in the temporary-home test helper.
templates/cli/internal/cmd/fanout_test.go Clears inherited XDG configuration for the isolated fan-out test.
templates/cli/internal/cmd/generate_test.go Clears inherited XDG configuration in the default-endpoint test.
templates/cli/internal/config/config_test.go Tests XDG directory selection and preference writes, including the missing-directory fallback.
templates/cli/internal/config/global.go Adds shared config-directory selection and routes preference paths through it.
tests/e2e/languages/cli/main.go Pins subprocess XDG configuration inside the harness's temporary home.

Reviewed the commits since 7f66250 · Details · Comment @hansi-codes review to re-run, or mention @hansi-codes with a question.

@hansi-codes hansi-codes Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Tier S · Looks good to merge. Summary

Issue #131 asks for the home directory whenever the XDG base directory is missing, rather than creating it. Tests that sandbox HOME now clear XDG_CONFIG_HOME too, so a developer's own XDG preferences cannot leak into them.
hansi-codes[bot]
hansi-codes Bot previously requested changes Oct 16, 2026

@hansi-codes hansi-codes Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Tier B · 1 blocking finding to address. Summary

Comment thread templates/cli/internal/config/global.go Outdated
Falling back to ~/.appwrite when XDG_CONFIG_HOME does not exist yet sends a user who points it at a new path to the home directory, and once ~/.appwrite exists it wins from then on. Apps create their XDG directories, so the missing-directory case now pins that and #131's fallback wording is deliberately not followed.

@hansi-codes hansi-codes Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Tier S · Looks good to merge. Summary

@hansi-codes
hansi-codes Bot dismissed their stale review October 16, 2026 07:44

The findings that requested changes are resolved. See the summary comment for what is still open.

@ChiragAgg5k
ChiragAgg5k merged commit d50ff37 into main Oct 16, 2026
61 checks passed
@ChiragAgg5k
ChiragAgg5k deleted the feat/cli-xdg-config branch October 16, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Honour XDG_CONFIG_HOME for the CLI config directory 🚀 Enhancement: xdg spec

1 participant