cabal icon indicating copy to clipboard operation
cabal copied to clipboard

Does cabal-3.10 impose `setup.Cabal < 3.12`?

Open andreasabel opened this issue 10 months ago • 36 comments

When trying to make cabal-3.10 build packages with custom setups on GHC 9.10.0 (alpha3), which ships with Cabal-3.12, cabal insists to build Cabal-3.10.3.0. If I try to force using the installed Cabal, constraint solving fails.

system-filepath-0.4.14$ cabal build -w ghc-9.10.0 -c 'setup.Cabal >=3.12'
Resolving dependencies...
Error: cabal: Could not resolve dependencies:
[__0] trying: system-filepath-0.4.14 (user goal)
[__1] next goal: system-filepath:setup.Cabal (dependency of system-filepath)
[__1] rejecting: system-filepath:setup.Cabal-3.12.0.0/installed-c30b
(constraint from maximum version of Cabal used by Setup.hs requires <3.12)

The package itself does not impose an upper bound on Cabal:

custom-setup
  setup-depends: Cabal >= 1.8, base >=4.0 && <5

This is not a problem with cabal-3.11 (master), this one does not impose this upper bound.

The docs say (https://cabal.readthedocs.io/en/3.10/cabal-package.html#pkg-field-custom-setup-setup-depends):

If the field is not specified the implicit package set will be used. The package set contains packages bundled with GHC (i.e. base, bytestring) and specifically Cabal. The specific bounds are put on Cabal dependency: lower-bound is inferred from cabal-version, and the upper-bound is < 1.25.

(Ok, the "< 1.25" is definitively stale doc here.) The docs seem to say that the upper bound comes from whatever is bundled with GHC, which should be including Cabal-3.12 (bundled with GHC 9.10 alpha3).

andreasabel avatar Apr 22 '24 14:04 andreasabel

Ruining my CIs...: https://github.com/BNFC/bnfc/actions/runs/8800309303/job/24151220023#step:15:28

andreasabel avatar Apr 23 '24 12:04 andreasabel

@ffaf1: This issue prevents me from evaluating Cabal-3.12 with a released cabal-install, and the following one with master:

  • https://github.com/haskell/cabal/issues/9940

Not sure how I should verify relaxations to Cabal < 3.13 in my projects now...

andreasabel avatar Apr 27 '24 19:04 andreasabel

This is expected behavior:

https://github.com/haskell/cabal/blob/bccc59f78f64d8db8605380d6735e0730d8bea23/cabal-install/src/Distribution/Client/ProjectPlanning.hs#L1397-L1414

Bodigrim avatar Apr 27 '24 19:04 Bodigrim

Thanks for digging this out @Bodigrim!

Maybe one should not have search through the source code of cabal to get this information.

  1. The docs (see OP) need to mention this.

  2. The reason for the constraint should be clearer. Currently it says:

    (constraint from maximum version of Cabal used by Setup.hs requires <3.12)

    Better formulation:

    (the use of cabal 3.10.* limits the maximum version of Cabal used by Setup.hs to <3.12)

I am also a bit skeptical about placing this limit in the first place.

As we can't predict the future, we also place a global upper bound on the lib:Cabal version we know how to interact with

This sound to me like:

As I cannot predict whether my house will stand for 50 years, I will tear it down after 20 years.

I do not see the point of forcing pessimism into the constraint solving here. Should things actually break with a too new Cabal, then I can always place a suitable upper bound with -c setup.Cabal < VERSION, or can't I?

andreasabel avatar Apr 27 '24 20:04 andreasabel

I am also a bit skeptical about placing this limit in the first place.

Given that Cabal-X is usually released a few weeks earlier than cabal-install-X, the limitation is quite annoying.

Could it be "current version + 4"? So that cabal-install-3.10 could be used to test Cabal-3.12, hoping that cabal-install-3.12 will be available in time for Cabal-3.14.

Bodigrim avatar Apr 27 '24 20:04 Bodigrim

The original issue seems to be:

  • #415

However this issue only speaks about warnings which I find totally appropriate.
So we would want a warning if cabal-x builds Setup.hs with Cabal-y where y is a release version bigger than x rather than a hard constraint one cannot overwrite.

The commit that introduced the OP is https://github.com/haskell/cabal/commit/c92b71502787acd40bb5012422f80150a6f112c5. It has no tests and no doc changes may thus be simply revertible.

andreasabel avatar Apr 28 '24 06:04 andreasabel

Thank you for the report. I think you are right the documentation is outdated and too flimsy here. Let's discuss the proposal to revert https://github.com/haskell/cabal/commit/c92b71502787acd40bb5012422f80150a6f112c5. If agreed upon, that would go into cabal 3.14, I imagine. A PR with the revert would be useful (once our CI gets fixed).

Beyond the documentation and the proposal, is there anything else in this ticket? Any bug in cabal 3.12 or 3.10, for example?

Mikolaj avatar Apr 29 '24 08:04 Mikolaj

Any bug in cabal 3.12 or 3.10, for example?

Well, I'd say the behavior I report here is a bug, others might disagree, e.g. @hvr who authored said commit. It is certainly limiting cabal-install without known workaround.

andreasabel avatar Apr 29 '24 10:04 andreasabel

I should have been more precise: any bug introduced in cabal 3.10 or 3.12?

Mikolaj avatar Apr 29 '24 11:04 Mikolaj

I think it makes sense to have some kind of support window like this for older versions of cabal-install because there's no guarantee an old version of cabal-install will know how to interact with a ./Setup built with a new version of Cabal.

By similar reasoning, if you want to build packages which use a new version of Cabal library then you need to use a tool which knows how to communicate with that (and there's no guarantee that the interface will happen to be the same as before).

  • Older versions might not pass a specific flag which is now needed for the build to work
  • Older versions might pass a flag which doesn't exist anymore

Possible failures include:

  • Loud confusing failures about passing unknown arguments to newer Cabal library versions.
  • Silent failures, where not everything you expect to be built is built or things are built incorrectly.

Perhaps the right solution is a flag to allow power users to opt out of this constraint and venture into any unknown territory if they desire but I thin forcing general users to upgrade to something which works is a better overall experience.

mpickering avatar Apr 29 '24 11:04 mpickering

Perhaps the right solution is a flag to allow power users to opt out of this constraint and venture into any unknown territory if they desire.

I think this is a very good way forward.

w/r/t broken CIs, can this be worked around. Can cabal make something immediate that eases the pain on users?

ffaf1 avatar Apr 29 '24 11:04 ffaf1

Let me repeat the question: could we change something small in cabal 3.12 that would help in some of the cases? Or in cabal 3.14 if there's a risk that'd break things?

Mikolaj avatar May 02 '24 09:05 Mikolaj

See also https://github.com/haskell/haskell-language-server/issues/4196 and https://github.com/haskell/cabal/issues/9632 it links to (please tell me if these are unrelated to the current issue).

Mikolaj avatar May 08 '24 22:05 Mikolaj

@mpickering wrote:

Perhaps the right solution is a flag to allow power users to opt out of this constraint and venture into any unknown territory

Why yet another flag? cabal is already giving a loud warning whenever it is used with a new version of GHC it as not been certified for. Wouldn't the same suffice for a newer version of Cabal?

andreasabel avatar May 09 '24 04:05 andreasabel

+1 for a warning. If the user hasn't set an upper bound then they're asking to use whatever new version of Cabal comes along. That may not be a good idea, but it's what they asked for! By all means warn if it's worrying, but it's quite annoying to not follow what the user stated.

michaelpj avatar May 10 '24 09:05 michaelpj

Cabal developer meeting 2024-05-23 gave no objections against removing the constraint and instead throw a warning, preferably in cabal build (rather than in cabal check). Removing the constraint can be done here: https://github.com/haskell/cabal/blob/bccc59f78f64d8db8605380d6735e0730d8bea23/cabal-install/src/Distribution/Client/ProjectPlanning.hs#L1265 If anyone has a pointer where to throw warnings in preparations of cabal build (like when we start the constraint solver), I would be grateful!

Would this proposal (replace by warning) find a general consensus?
(Pinging @Bodigrim @mpickering.) Would be good to resolve this issue soon...

andreasabel avatar May 23 '24 17:05 andreasabel

Pointers towards implementing a warning:

  • Possibly warn just before or after writing plan.json: https://github.com/haskell/cabal/blob/50d9f9cfc1ff7a36bdab0472de839f9e6dfc0a82/cabal-install/src/Distribution/Client/ProjectPlanning.hs#L592-L593
  • The structure holding the dependencies for e.g. the setup component: https://github.com/haskell/cabal/blob/50d9f9cfc1ff7a36bdab0472de839f9e6dfc0a82/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs#L666-L675
  • Identifying the setup component in the plan: https://github.com/haskell/cabal/blob/50d9f9cfc1ff7a36bdab0472de839f9e6dfc0a82/cabal-install-solver/src/Distribution/Solver/Types/ComponentDeps.hs#L66

andreasabel avatar May 23 '24 18:05 andreasabel

Would this proposal (replace by warning) find a general consensus?

I'm in favor.

Bodigrim avatar May 23 '24 19:05 Bodigrim

@mpickering: you had concerns and you favoured a poweruser flag. Would a warning make sense to you, too? How specific the warning would need to be? Would a cheap warning whenever that the user hasn't set an upper bound (regardless of whether this affected the build plan) be good enough?

Mikolaj avatar May 27 '24 07:05 Mikolaj

I have encountered the same issue in the context of any constraints. For instance, if you attempt to compile a project with:

  1. A custom Setup.hs script

  2. cabal-install-3.10.* + ghc-9.10.*

  3. The following cabal.project.local file:

    constraints: any.Cabal installed
    

Then cabal will reject the build plan with a similar error, even though I have not placed an upper bound on Cabal in the .cabal file:

$ cabal build -w ghc-9.10
Resolving dependencies...
Error: cabal: Could not resolve dependencies:
[__0] trying: cabal-sandbox-0.1 (user goal)
[__1] next goal: cabal-sandbox:setup.Cabal (dependency of cabal-sandbox)
[__1] rejecting: cabal-sandbox:setup.Cabal-3.12.0.0/installed-be90 (constraint
from maximum version of Cabal used by Setup.hs requires <3.12)

This is especially annoying now that haskell-ci generates installed constraints that use any, so I can't use haskell-ci in my project with a custom Setup.hs script anymore.

RyanGlScott avatar May 28 '24 10:05 RyanGlScott

We don't shaft users, this has to make next cabal-install release.

ffaf1 avatar May 28 '24 10:05 ffaf1

@Mikolaj I don't have any particular more comments to what I already made (there is no a priori reason that using a new Cabal library version will continue to work with an old cabal-install release).

@RyanGlScott It seems like a bug in haskell-ci to force you to used the installed Cabal library version?

mpickering avatar May 28 '24 10:05 mpickering

It seems like a bug in haskell-ci to force you to used the installed Cabal library version?

I don't think I know enough about haskell-ci's design considerations to say for sure. That being said, given that there is (seemingly) no workaround for this bug other than to remove the use of any, I've requested that haskell-ci allow toggling the use of any in https://github.com/haskell-CI/haskell-ci/issues/728.

RyanGlScott avatar May 28 '24 11:05 RyanGlScott

Could it be "current version + 4"?

That would require to be more careful about backward compatibility of ./Setup interface.

I'd say that promptly managing the cabal-install releases should be easier.

phadej avatar May 28 '24 11:05 phadej

I am also a bit skeptical about placing this limit in the first place.

It's like having base <5. Just remove all the upper bounds everywhere!

I don't trust that in the possible future case that cabal-install-x.y.z.w won't work with Cabal-x.y+2, the proper bug fix will be promptly released. Nor there are possibility to make a "revision" do disallow that combination, the broken cabal-install-x.y.z.w will be there, and people would need find out they need to upgrade.

phadej avatar May 28 '24 11:05 phadej

I am also a bit skeptical about placing this limit in the first place.

It's like having base <5. Just remove all the upper bounds everywhere!

cabal-install-3.10 does not force base < 4.20 and shouldn't force Cabal < 3.12 either. Let the developer decide whether to take a optimistic or pessimistic approach to the possibility of breakage by future changes.

Upper bounds are needed to prevent build failures. So one can remove upper bounds for which no build failures are known. Preferably one will respond quickly to build failures by adding upper bounds through hackage revisions.

in the possible future case that cabal-install-x.y.z.w won't work with Cabal-x.y+2, the proper bug fix

The proper fix is then to add a Cabal < 3.13 bound to your setup-depends. No action needed from the maintainers of Cabal. Why should this be so different from other upper bounds? The caution will have Cabal < 3.13 anyways, the gamblers might not have it, but let them gamble!

andreasabel avatar May 28 '24 11:05 andreasabel

Let the developer decide whether to take a optimistic or pessimistic approach to the possibility of breakage by future changes.

The cabal-install is "the developer" there. It calls ./Setup interface. If Cabal-x.y+2 changes something, cabal-install-x.y cannot know. This "internal" dependency of cabal-install on Cabal (in case of custom-setup packages) is not editable by hackage revisions.

The proper fix is then to add a Cabal < 3.13 bound to your setup-depends.

It's not as I try to explain. The cabal-install-3.14 would work without the constraint, cabal-install-3.12 won't.

phadej avatar May 28 '24 11:05 phadej

Re haskell-ci issue. In the future, once we test GHC release alphas and candidates, it would be great if there were corresponding cabal-install release candidates so we can test that bundled ./Cabal version etc. works with build-type: Custom packages.

Ltely GHC release management has been improved, the GHC-9.10.1 was released on the date advertised few months in advance, so it should be possible to get cabal-install released close to GHC releases in the future.

phadej avatar May 28 '24 11:05 phadej

@RyanGlScott have you considered using the prerelease advertized in the Cabal-3.12 announcement? It should work for custom setups. https://discourse.haskell.org/t/ann-cabal-3-12-0-0-released/9504#how-to-get-the-cabal-install-pre-release-3

ulysses4ever avatar May 28 '24 12:05 ulysses4ever

I will happily use cabal-install-3.12.0.0 once it is fully supported by ghcup and haskell-ci.

RyanGlScott avatar May 28 '24 12:05 RyanGlScott