Request for testing of the XDG-enabled cabal-install

Cabal, or more precisely cabal-install which is mostly known to Haskellers as the cabal command line program, recently merged a pull request that makes cabal support the XDG Basedir Specification. Previously, cabal would put all of its files in the ~/.cabal directory. Now the files are spread over multiple directories:

  • $XDG_CONFIG_HOME/cabal for the main configuration file. On Unix, this defaults to ~/.config/cabal.

  • $XDG_CACHE_HOME/cabal for downloaded packages and script executables. Defaults to ~/.cache/cabal on Unix.

  • $XDG_STATE_HOME/cabal for compiled libraries and other stateful artifacts. Defaults to ~/.local/state/cabal on Unix.

  • ~/.local/bin for executables installed with cabal install.

The advantage is mostly that cabal now behaves slightly more like other modern Unix tools. For example, it is easier to put all configuration files under version control if they’re all in the same subdirectory, and it is easier to delete all program caches when you’re low on disk space.

This is obviously a rather invasive change. Does it mean that the next version of cabal will break your workflow? Maybe! But if so, it is not intentional. This change comes with what I hope is rather thorough backwards compatibility behaviour. Basically, if ~/.cabal exists, or $CABAL_DIR is set, the old behaviour of using a single unified directory will be maintained. And of course, most paths can
still be configured manually in the configuration file.

Still, because of the delicacy of a change like this, we’d like some external confirmation that cabal is still usable. This requires human trials. Therefore, if you are a human who uses cabal, please
try installing the latest development version
and see if it still works for you. If you want to try out the new XDG future, you can delete your ~/.cabal directory (possibly copying ~/.cabal/config to ~/.config/cabal/config first). I’ve been dogfooding this support for a few months, but I have no illusions about my usage covering the full feature space.

Beyond whether cabal remains at all functional, I am personally curious whether the XDG simulacrum that is implemented on Windows is at all useful for Windows users, or whether it would be better for
cabal to retain a single unified directory on that platform.

15 Likes

A great improvement, and one less dotfile polluting my home directory! Thanks for your contribution @athas!

3 Likes

Great work, thanks for modernizing cabal configuration.
I would like to note cabal ci generates prebuilt binaries for linux, windows and mac for each commit in master. So you dont need built cabal from source to test the new feature.

For example the last commit artifacts are here.

Artifacts of the pull request adding xdg support are here

3 Likes

Does that mean that there is a simple ghcup command people could run to get it?

1 Like

Yes, rummaging in Matrix backlog I find

ghcup --no-cache install cabal -u 'https://gitlab.haskell.org/haskell/cabal/-/jobs/1124022/artifacts/raw/out/cabal-install-3.8.1.0-x86_64-linux-alpine.tar.xz?inline=false' head

so substituting the path with the new artefact (from the list @jneira provided) should do the trick.

This is probably me, but I’m having some trouble figuring out the right URL to pass to ghcup here. Going to the artifacts list of the latest merge to master, I can indeed download the Linux artifact in my web browser, but neither the link that that button ostensibly points to, nor the link that I see in the web development tools in my browser from which the file was actually downloaded (a different link, which looks temporary – has a urlExpires parameter), work when passing them to curl, let alone ghcup.

I also spelunked in the action logs of one of the Linux jobs but I didn’t find an artifact URL there either.

Does someone more knowledgeable about github actions know where to find an artifact URL that curl accepts (and thus hopefully also ghcup)?

1 Like

It seems you need to be logged in to download GitHub artifacts (you can confirm this by going to the github artifact page in incognito mode). If you are then you should be able to use this url: https://api.github.com/repos/haskell/cabal/actions/artifacts/404462746/zip (with the appropriate authorization in your headers). But that required authorization probably makes it impossible for GHCup to support this. And I would assume that GHCup also doesn’t expect a zip file like this.

Maybe @bgamari can trigger a build on the gitlab mirror? Or is this also in scope for @chreekat?

1 Like

My typical workflow involves nuking ~/.cabal periodically. I do this so often that I developed a muscle memory for this command. Since this directory doesn’t exist anymore, does it mean that the new cabal will come with the cabal nuke or cabal gc command to collect garbage in the store?

The XDG-based directory sounds more like an internal implementation detail and shouldn’t leak to end user. I shouldn’t remember to type $XDG_CONFIG_HOME/cabal (and I don’t want to type this verbose command actually). I believe, there should at least be a command like cabal cache-dir that outputs the cache directory to stdout so I can at least do rm -rf $(cabal cache-dir).

Moreover, this change will break a lot of CI setups that cache global ~/.cabal storage. I’m using a GitHub Actions template that uses the output of the haskell/actions/setup. So my CI shouldn’t be affected (as long as GitHub action is patched). But I believe it would be great to reach out to more CI users with this update to help them to migrate to a newer setup.

3 Likes

Oh, indeed, I haven’t tested this with github, only with gitlab. I’ve just pushed tag head-with-XDG-and-more (HEAD of cabal repo as of right now) and gitlab is already busy building it at Pipelines · Haskell / Cabal · GitLab, so this should solve the immediate problem (if it builds fine:).

Still, if github doesn’t work with ghcup, perhaps we should build at least each push to cabal’s master branch on gitlab?

Great! This works for me on MacOS (x86_64):

ghcup --no-cache install cabal -u 'https://gitlab.haskell.org/haskell/cabal/-/jobs/1207696/artifacts/raw/out/cabal-install-3.9-x86_64-darwin.tar.xz?inline=false' 3.9-xdg

This should work for most Linux distros:

ghcup --no-cache install cabal -u 'https://gitlab.haskell.org/haskell/cabal/-/jobs/1207691/artifacts/raw/out/cabal-install-3.9-x86_64-linux-deb10.tar.xz?inline=false' 3.9-xdg

And this should work on windows:

ghcup --no-cache install cabal -u 'https://gitlab.haskell.org/haskell/cabal/-/jobs/1207698/artifacts/raw/out/cabal-install-3.9-x86_64-windows.zip?inline=false' 3.9-xdg
1 Like

There is no cabal nuke or cabal gc under development (the latter is probably unsafe because there might be untracked dynamic executables pointing at its contents). I’m not sure adding such a command to cabal itself is appropriate, since they seem to be very workflow-dependent: my practice of “nuking” preserves the config file, while yours does not.

A cabal cache-dir command would not be difficult to add, but it’s probably not what you want. The store is not part of the cache, but instead part of the “state”. We can add distinct cabal cache-dir and cabal state-dir subcommands and hope that’s where it ends. Alternatively, a cabal list-dir command like how cabal list-bin works.

Good point about the CI caching issue. That’ll probably be a bit painful for a little while. One solution is to have CI jobs set a CABAL_DIR=$HOME/.cabal environment variable, as this preserves the old behaviour (XDG behaviour isn’t useful in CI anyway).

1 Like

But there is an open issue about it and an experimental third party cabal-store-gc tool that kind of works.

1 Like