daemon: honour XDG layout when run as an installed service#106
Merged
Conversation
`gortex daemon install-service` wrote a launchd plist / systemd --user unit that propagated only PATH. launchd and systemd --user start the daemon with a near-empty environment — they do not inherit the XDG_* variables a user exports from their shell or session manager. Path resolution reads those variables at runtime, so the supervised daemon fell back to ~/.gortex even when the user had opted into an XDG layout, silently splitting their state across two trees. Capture the absolute XDG_CONFIG_HOME / XDG_DATA_HOME / XDG_CACHE_HOME values in effect at install time and bake them into the service unit's environment, applying the same absolute-only rule platform.unifiedDir uses. XDG_RUNTIME_DIR is intentionally excluded — the init system sets it per session. Re-run install-service to re-capture changed values. Rendering moves into pure renderLaunchdPlist / renderSystemdUnit helpers with format-correct escaping: XML-escape plist string values, and escape systemd Environment= values (%% specifier escape, plus double-quoting for whitespace).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Fixes #105.
gortex daemon install-servicewrites a launchd plist (macOS) / systemd--userunit (Linux) that propagated onlyPATHinto the supervised process. launchd and systemd--userstart the daemon with a near-empty environment — they do not inherit theXDG_*variables a user exports from their shell or session manager (e.g. nix/home-manager).Path resolution (
internal/platform/xdg.go) reads those variables at runtime, so with them absent the daemon falls back to~/.gortexeven when the user opted into an XDG layout. Net effect from the issue's repro:gortex install(run in the XDG-configured shell) correctly writes under$XDG_CONFIG_HOME/gortex, but starting the service then creates~/.gortex— silently splitting state across two trees.This affected both macOS launchd and Linux systemd
--user(the systemd unit had noEnvironment=lines either).Fix
At install time — which runs in the user's shell, where the variables are present — capture the absolute
XDG_CONFIG_HOME/XDG_DATA_HOME/XDG_CACHE_HOMEvalues and bake them into the service unit's environment:EnvironmentVariablesdict (alongsidePATH).Environment=lines in[Service].Details:
platform.unifiedDir(a relative XDG path is ignored per the XDG Base Directory spec).XDG_RUNTIME_DIRis intentionally excluded — the init system sets it per session; pinning an install-time value would point the Linux socket at a stale runtime dir.renderLaunchdPlist/renderSystemdUnithelpers with format-correct escaping: XML-escape plist string values; for systemd, escape%→%%(specifier introducer) and double-quote whitespace values.install-servicere-captures changed values (documented indocs/onboarding.mdand in code).No behaviour change for users without an XDG override: with nothing captured the plist/unit render exactly as before (PATH-only / no
Environment=).Note on the issue's suggested behaviour
The report suggested the daemon "check if a config exists under the XDG path." That isn't possible without the variable set — Gortex deliberately uses a unified
~/.gortexunless an absoluteXDG_*_HOMEis explicitly present, so the env var is the only signal of intent. This PR makes that signal survive into the service, which is the capture approach the issue's own footnote anticipated.Tests
cmd/gortex/daemon_service_test.go: render helpers exercised for the no-XDG baseline (no stray env / blank lines) and the populated case (regression test for the bug), XML-escaping, systemd whitespace-quoting and%-escaping, and thexdgServiceEnvabsolute-only filter. Plist output asserted to be well-formed XML.go build ./cmd/gortex/(CGO),go vet,golangci-lint, andgo test -raceof the touched tests all green.