Skip to content

Use XDG base directories and Known Folders on Windows - #1809

Open
bioball wants to merge 2 commits into
apple:mainfrom
bioball:xdg-default-dirs
Open

Use XDG base directories and Known Folders on Windows#1809
bioball wants to merge 2 commits into
apple:mainfrom
bioball:xdg-default-dirs

Conversation

@bioball

@bioball bioball commented Aug 3, 2026

Copy link
Copy Markdown
Member

This changes logic that previously read/wrote from ~/.pkl to use XDG base directories (all OSes), and Known Folders locations on Windows.

For example, Pkl will look for settings.pkl in:

  1. $XDG_CONFIG_HOME/pkl/settings.pkl
  2. %APPDATA/pkl/settings.pkl
  3. Path pkl/settings.pkl within $XDG_CONFIG_DIRS
  4. /etc/xdg/pkl/settings.pkl
  5. ~/.pkl/settings.pkl

The settings and cacerts dirs will still read from the legacy ~/.pkl/ directory if not found in the new locations.

See https://specifications.freedesktop.org/basedir/latest/

This changes logic that previously read/wrote from `~/.pkl` to use
XDG base directories (all OSes), and Known Folders locations on Windows.

For example, Pkl will look for `settings.pkl` in:

1. `$XDG_CONFIG_HOME/pkl/settings.pkl`
2. `%APPDATA/pkl/settings.pkl`
3. `~/.pkl/settings.pkl`
4. Path pkl/settings/pkl within `$XDG_CONFIG_DIRS`
5. `/etc/xdg/pkl/settings.pkl`

The settings and cacerts dirs will still read from the legacy `~/.pkl/`
directory if not found in the new locations.

@HT154 HT154 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!


=== Changes

* Default the CLI's package cache, settings file, CA certificates directory, and REPL history to XDG-style locations instead of `~/.pkl`: `~/.cache/pkl`, `~/.config/pkl/settings.pkl`, `~/.config/pkl/cacerts`, and `~/.local/state/pkl/repl-history` (pr:https://github.com/apple/pkl/pull/1674[]).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: took me a couple scans to parse "default" as a verb

Suggested change
* Default the CLI's package cache, settings file, CA certificates directory, and REPL history to XDG-style locations instead of `~/.pkl`: `~/.cache/pkl`, `~/.config/pkl/settings.pkl`, `~/.config/pkl/cacerts`, and `~/.local/state/pkl/repl-history` (pr:https://github.com/apple/pkl/pull/1674[]).
* Use XDG-style locations by default for the CLI's package cache, settings file, CA certificates directory, and REPL history instead of `~/.pkl`: `~/.cache/pkl`, `~/.config/pkl/settings.pkl`, `~/.config/pkl/cacerts`, and `~/.local/state/pkl/repl-history` (pr:https://github.com/apple/pkl/pull/1674[]).

Comment on lines +28 to +31
| Package cache
| `~/.cache/pkl`
| `$LOCALAPPDATA/pkl/Cache`
| none

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wonder if it might make sense to have a one-time "new cache not found, but old cache is present" copy/link migration to make some attempt to reuse existing cache dirs. Cost to re-build is low, but still non-zero, especially on slow connections.

Comment thread pkl-core/src/test/kotlin/org/pkl/core/util/IoUtilsTest.kt Outdated
Comment thread pkl-executor/src/main/java/org/pkl/executor/ExecutorOptions.java Outdated

private fun HttpClient.Builder.addDefaultCliCertificates() {
val caCertsDir = IoUtils.getPklHomeDir().resolve("cacerts")
val caCertsDir = IoUtils.getSystemCaCertsDir()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The change to cacerts means that the certs can now be silently diverted via an env var. I'm not sure this is a good call security-wise.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Is this any different from diverting the path of the settings.pkl via an env var? Both have security implications.

Path candidate;
if (home != null) {
candidate = home.resolve(subpath);
if (Files.exists(candidate)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

File.exists means a file named cacerts will return a candidate, but later we check if it's a directory, which will fail, meaning we'll use the default bundled certs even if there's a valid one somewhere else.
Worth adding another parameter or predicate to check the correct expectation.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good point; I changed this to accept a predicate.

Comment thread docs/modules/release-notes/pages/0.33.adoc
Comment thread docs/modules/release-notes/pages/0.33.adoc Outdated
Comment thread docs/modules/release-notes/pages/0.33.adoc Outdated
Comment thread stdlib/settings.pkl Outdated
Comment thread stdlib/settings.pkl Outdated
Comment on lines +21 to +22
/// Unless CLI commands and build tool plugins are explicitly configured with a settings file,
/// they will use `~/.pkl/settings.pkl` or the defaults specified in this module.
/// looks in the following locations in order of precedence:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Wording is strange here.
What looks in the following locations?

@bioball bioball Aug 6, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Updated this; the subject is "CLI commands and build tool plugins"

Comment thread docs/modules/pkl-cli/partials/cli-common-options.adoc Outdated
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.

4 participants