Feature Request: --ignore-constraints #949

Closed
dagit opened this Issue Jun 1, 2012 · 18 comments

Projects

None yet

9 participants

@dagit
Collaborator
dagit commented Jun 1, 2012

What if Cabal offered a --ignore-constraints where it ignored the package's constraints and tries to find an install plan simply based on the set of packages that you need?

I base this on the following workflow:

  • cabal(-dev) install fails
  • cabal unpack foo
  • vim foo.cabal to remove all constraints (except the ones on base)
  • cabal(-dev) install now works

What if I could do this instead:

  • cabal(-dev) install fails
  • cabal(-dev) install --ignore-constraints

I'm kind of torn about this because on the one hand cabal is smart enough to usually find a set of versions that are compatible but on the other hand people test their code against some (possibly very different) set of versions. Just because cabal can find a set of versions that satisfies the constraints doesn't mean you'll get a valid library/executable or even one that builds.

@kosmikus
Collaborator
kosmikus commented Jun 2, 2012

Yes, something like this should certainly be done. But --ignore-constraints alone is going to be too permissive in many cases. So it becomes mainly an UI question. Which set of what I call "index-edit" commands should be supported?

@thielema
thielema commented Jun 9, 2012

Accidentally I had a similar idea today.
I would find it better to ignore the constraints only for selected packages. E.g. --ignore-constraint=mtl. Then whereever 'mtl' is imported its dependency constraints are ignored.
An alternative option might be: --override-constraint=mtl-2.1.1. Then mtl-2.1.1 is used regardless of what the Build-Depend fields say. However this might be achieved as well by a combination of --ignore-constraint=mtl and --constraint='mtl==2.1.1'.

However, it is certainly better if the installed packages get versions different from original ones, where cabal has to actually override the Build-Depends constraints. E.g. if happstack-server-6.6.5 has Build-Depends: mtl>=2 && <2.1, then the installed version of happstack-server-6.6.5 should not be build against mtl-2.1.1, because this contradicts the constraints of happstack-server-6.6.5. Instead, the package should be installed as happstack-server-6.6.5.1.

Finally, if a build with overridden constraints succeeds then cabal should emit a diff of cabal files that a user can send to the package author. Even better cabal would create a darcs or git patch against the repository that is declared in the Cabal package description. I am just dreaming.

@LeventErkok

It'd be nice if ghc-pkg kept track of "--ignore-constraints", so it can at least list that when a package is queried later on.

@feuerbach
Contributor

At least please implement --ignore-constraints as is. From experience, it would solve 95% of my problems with cabal, since I do exactly what Jason describes above.

@peti
Contributor
peti commented Nov 11, 2012

These problems are caused by an asymmetry in the UI: Users can extend the set of unacceptable packages by adding appropriate --constraint flags on the command-line. However, users cannot extend the set of acceptable packages that way.

For example, consider the well-known utility rsync. It offers two ways to specify the set of files that's being operated on: a white-list (--include) and a black-list (--exclude). These two mechanisms can then be combined in clever ways that turn out to be very expressive.

Cabal-install, on the other hand, offers a black-list, but it doesn't offer a white-list.

@nomeata
Contributor
nomeata commented Oct 5, 2013

Yes, please add such a flag so that maintainers can follow the PVP without preventing daring users from ignoring an upper bound on a dependency. (related blog post)

@23Skidoo
Member
23Skidoo commented Oct 5, 2013

Should all constraints be ignored or just upper bounds?

@23Skidoo
Member
23Skidoo commented Oct 5, 2013

My UI proposal:

  • --ignore-upper-bounds - ignore upper bounds for all packages.
  • --ignore-upper-bounds=package-a,package-b,package-c - ignore upper bounds only for package-a, package-b and package-c.
@nomeata
Contributor
nomeata commented Oct 5, 2013

I think the UI can be more general than just being about upper bounds.

There are many variations that might work. I think one of the easiest is to have --override-constraint=foo-1.2.3 mean that every package’s version constraints on foo are ignored.

Maybe that is the reason why this bug has not been tackled yet: A difficult and large UI design space.

@23Skidoo
Member
23Skidoo commented Oct 5, 2013

I think the UI can be more general than just being about upper bounds.

Well, obviously it can be more general, but does it need to be? As @kosmikus noted above, simply ignoring constraints will be too permissive in many cases. My conjecture is that ignoring upper bounds will be enough to solve most problems caused by too-strict version ranges, and ignoring lower bounds is usually not desired.

One question is what to do with constraints that are more complex than just A >= $LOWER && A < $UPPER. E.g. (A >= $LOWER_1 && A < $UPPER_1) || A >= $LOWER_2 where the version range >= $UPPER_1 && < $LOWER_2 is marked as broken.

@thielema
thielema commented Oct 5, 2013

On Sat, 5 Oct 2013, Mikhail Glushenkov wrote:

One question is what to do with constraints that are more complex than just A >= $LOWER && A < $UPPER. E.g.
(A >= $LOWER_1 && A < $UPPER_1) || A >= $LOWER_2 where the version range >= $UPPER_1 && < $LOWER_2 is marked
as broken.

It should certainly ignore the upper-most version bound, because this is
the one that prevents cabal from using the newest package version.

@nomeata
Contributor
nomeata commented Oct 5, 2013

--ignore-upper-bounds=package-a,package-b,package-c - ignore upper bounds only for package-a, package-b and package-c.

Should this refer to upper-bounds specified in package-a, or upper bounds in dependencies on package-a?

@23Skidoo
Member
23Skidoo commented Oct 5, 2013

@nomeata

Should this refer to upper-bounds specified in package-a, or upper bounds in dependencies on package-a?

The latter. Perhaps worth renaming it to --ignore-upper-bounds-on=package-a,package-b to make it more obvious.

@nomeata
Contributor
nomeata commented Oct 5, 2013

The latter. Perhaps worth renaming it to --ignore-upper-bounds-on=package-a,package-b to make it more obvious.

Even that can be confusing. How about --allower-newer; that is pretty unambiguous.

@23Skidoo
Member
23Skidoo commented Oct 5, 2013

Yes, --allow-newer sounds better.

@ygale
Contributor
ygale commented Oct 6, 2013

Sounds like we are close to a consensus. And see, for example, this reddit thread for evidence that this is widely considered an import and urgent feature to add.

Can we please make this new option also available from the local cabal.config?

@peti
Contributor
peti commented Oct 6, 2013

cabal-install can add further version restrictions with the --constraint flag. What it lacks, though, is the inverse operation: to lift version restrictions through a, say --permit flag. Many other programs offer exactly that kind of symmetry in their UI with great success. Consider rsync as an example. The tools accepts flags --include and --exclude, and matches them in the order in which they are specified.

cabal-install could easily do the same thing. To lift all version restrictions (in dependencies) on a package foo, just say:

cabal install --permit "foo any" bar

That UI seems more general to me than the --allow-newer flag that's been suggested. Arguably, --allow-newer would do a different thing than --permit would, so both flags might be nice to have. I just feel that --permit would allow me to express what I want more accurately than --allow-newer would.

Anyway, in NixOS we kind of achieve this stuff by running the jailbreal utility as part of the build procedure. This tool has solved the vast majority of issues we've had trying to update packages. It would be nice to have this functionality available directly in Cabal, too.

@ygale
Contributor
ygale commented Oct 11, 2013

See also discussion in #1519 of the proposed related flags --ignore-all-frozen and --ignore-frozen in that context.

@23Skidoo 23Skidoo was assigned Dec 5, 2013
@23Skidoo 23Skidoo closed this in #1604 Dec 9, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment