Skip to content

Is ~/.cabal/config supposed to be used when exists, in the absence of envvars and XDG folder? #10713

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Bodigrim opened this issue Jan 5, 2025 · 18 comments

Comments

@Bodigrim
Copy link
Collaborator

Bodigrim commented Jan 5, 2025

cabal/doc/config.rst

Lines 80 to 86 in ed1e4d7

The configuration file location is determined as follows:
1. If option ``--config-file`` is given, use it;
2. otherwise, if ``$CABAL_CONFIG`` is set use it;
3. otherwise, if ``$CABAL_DIR`` is set use ``$CABAL_DIR/config``;
4. otherwise use ``config`` in ``$XDG_CONFIG_HOME/cabal``, which
defaults to ``~/.config/cabal`` on Unix.

The documentation means that unless --config-file / $CABAL_DIR / $CABAL_CONFIG are set explicitly, ~/.cabal/config won't ever be used even if it exists and ~/.config/cabal does not. Yet, reading https://github.com/haskell/cabal/blob/master/cabal-install/src/Distribution/Client/Config.hs, I believe this is untrue. Could it please be reconciled?

Cf. haskell-CI/haskell-ci#655

@Bodigrim Bodigrim changed the title Is ~/.cabal/config is supposed to be used when exists or not, in the absence of envvars? Is ~/.cabal/config is supposed to be used when exists, in the absence of envvars and XDG folder? Jan 5, 2025
@Bodigrim Bodigrim changed the title Is ~/.cabal/config is supposed to be used when exists, in the absence of envvars and XDG folder? Is ~/.cabal/config supposed to be used when exists, in the absence of envvars and XDG folder? Jan 5, 2025
@Bodigrim
Copy link
Collaborator Author

Folks, what's needed to make progress on this issue? Could you please decide what is the expected behavior? Is it a bug in documentation or a bug in implementation?

@athas
Copy link
Collaborator

athas commented Feb 13, 2025

The existence of the ~/.cabal directory is interpreted equivalent to CABAL_DIR being set. It is documented here:

cabal/doc/config.rst

Lines 63 to 67 in ed1e4d7

For backwards compatibility, if the directory ``~/.cabal`` on
Unix or ``%APPDATA%\cabal`` on Windows exists, and
``$XDG_CONFIG_HOME/cabal/config`` does not exist, and
``CABAL_DIR`` is unset, ``cabal-install`` will behave as if
``CABAL_DIR`` was set to point at this directory.

@athas
Copy link
Collaborator

athas commented Feb 13, 2025

This backwards compatibility logic is pretty convoluted. Maybe it is better to start removing it.

@Bodigrim
Copy link
Collaborator Author

@athas so you are saying that in the passage I quoted $CABAL_DIR refers not to a vanilla $CABAL_DIR in environment, but to a $CABAL_DIR as defined a few paragraphs above. Honestly, this expects too much from a reader. Could the documentation please be brought to a state where it gives an unambigious and self-contained instruction how Cabal finds its config file?

@Bodigrim
Copy link
Collaborator Author

@Mikolaj @ulysses4ever @geekosaur @ffaf1 et al., any chance you can discuss the issue and decide who is correct, documentation or implementation, please?

@athas
Copy link
Collaborator

athas commented May 29, 2025

I suggest simplifying the implementation by removing some of the convoluted backwards compatibility logic. The implementation reflects the behaviour that was decided on in the various PRs and issues that led to it. The documentation does explain all of the mechanisms, although perhaps it is too scattered. Of course I have no opposition to improving the clarity of the documentation.

@geekosaur
Copy link
Collaborator

I worry somewhat about the repercussions of changing the logic, especially since I still have to maintain a mode-0 file ~/.cabal to prevent random pre-XDG-cabal things from recreating ~/.cabal and duplicating my store et al. (I consider the need for this a significant wart in the current state of things.)

@athas
Copy link
Collaborator

athas commented May 29, 2025

A simplification would be to say that ~/.cabal is only used if CABAL_DIR points to that directory. In fact, ~/.cabal would not be specially known to cabal at all. This does not prevent other tools from creating this directory, but it would prevent such creation from influencing cabal's behaviour. The main simplification is that the behaviour of cabal would no longer depend on the presence or absence of files, but only on the setting of environment variables. (The interaction between CABAL_CONFIG and CABAL_DIR is still a little subtle, but hopefully few people set them both.)

@Mikolaj
Copy link
Member

Mikolaj commented May 29, 2025

Regarding the documentation, yes, let's please improve it and let's make sure it explains the current implementation clearly.

Regarding simplifying the backward compatibility logic, IMHO, that train has sailed and now we are precisely in the period where predictable backward compatibility is essential. So, unless things are very broken, which I hope they are not, I'd recommend to wait with simplifying or removing the machinery until backward compatibility is not needed for 99.99% of users (e.g., thanks to old tools, tutorials and workflows that don't understand XDG being obsolete also due to other format or semantics changes and so won't be expected to inter-operate with new cabal binaries). I guess that's a few years of waiting.

This is tricky --- let's not forget we spent a lot of time discussing and approving this imperfect scheme and then IIRC we tweaked it radically once close enough to when it was released and, apparently, this is still not perfect. But it works.

@athas
Copy link
Collaborator

athas commented May 30, 2025

I am also reluctant to reopen that can of worms, but I do believe that if any change to the implementation is done, it should solely be to remove special cases. The best timing of such changes is not something I know much about. I don't know when the backwards compatibility stops being necessary, but it is my impression that the rate of users updating their Haskell tooling has increased significantly since the good old days when everyone used a cabal that had been tastefully aged in the Debian stable archives. The current behaviour has been in cabal for over two years.

@phadej
Copy link
Collaborator

phadej commented May 30, 2025

I expect that backward compatibility setup has ensured that people haven't moved to use new locations, except if they got brand new machines and made new clean setups.

In that light, two years is a short time.

@phadej
Copy link
Collaborator

phadej commented May 30, 2025

For the record, I was against backward shimming, and I'm still against CABAL_DIR stuff (just require all the paths to be explicitly configured if config file exists). There are just too much conditionals in that.

The fact that writing clear documentation is hard is a hint that design is too convoluted.

EDIT: The problem with CABAL_DIR is that even if user has their own cabal.config, if a new kind of a directory is added to cabal-install, then the default location based on CABAL_DIR will used which is then somewhere where user probably don't want it to be. In other words, the approach is not really future proof.

@athas
Copy link
Collaborator

athas commented May 30, 2025

I have made a PR that adds further clarification to the documentation: #10972

@geekosaur
Copy link
Collaborator

I'm still against CABAL_DIR stuff (just require all the paths to be explicitly configured if config file exists)

I must note that I need to use CABAL_DIR sometimes, because generate_bootstrap_plans (which uses Cabal-the-library) has a hardcoded reference to ~/.cabal which in my case needs to be overridden to the XDG path. I think the test suite also uses it to force tests to ignore user cabal config, so that tests are reproducible when run locally. So perhaps we want to simplify it instead of outright removing it?

@phadej
Copy link
Collaborator

phadej commented May 30, 2025

because generate_bootstrap_plans

I don't see a hard coded ~/.cabal in that script (nor comment mentioning if its implicit somehow). Even if it were, any automated usage can create a fully explicit cabal config file. It's quite trivial cat <<<EOF even in bash. If a script cares about particular cabal settings, it really should be explicit about those.

ath. I think the test suite also uses it to force tests to ignore user cabal config

And specifying fully explicit config with all paths explicitly pointing somewhere shouldn't be an issue there.

Rather the opposite, the less external and implicit factors affecting stuff there are the easier it should be to write environment independent tests.

@geekosaur
Copy link
Collaborator

I didn't dig up exactly what was failing, just that it's documented (and I keep getting reminded every time I run it) that it doesn't work with XDG paths and I have to force it to look in the right place for my XDG config.

@phadej
Copy link
Collaborator

phadej commented May 30, 2025

Documented where?

https://github.com/haskell/cabal/tree/master/bootstrap#updating-bootstrap-plans

Not there ATM at least. Nor in the script itself.

@geekosaur
Copy link
Collaborator

Oh, I erred, it's CABAAL_CONFIG not CABAL_DIR. It's at the end of https://github.com/haskell/cabal/wiki/Making-a-release#c3-bumping-version-numbers:

Re-generate the bootstrap build plans (json files) by running make bootstrap-jsons. If the program errors because it did not find your global configuration file, export an environment variable (e.g. export CABAL_CONFIG=~/.config/cabal/config) to fix the error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants