Added --oldest-deps flag, which builds using the oldest versions allowed #1309

wants to merge 4 commits into

8 participants


The --oldest-deps flag makes cabal prefer older version over newer versions when resolving dependencies.

This is useful for debugging to check whether the lower bounds of a package are still valid. The feature is best used on a separate package database or --one-shot to prevent messing up the global package database.

@craffit craffit Added --oldest-deps flag, which builds using the oldest versions alowed
This feature is useful for debugging to see whether the lower bounds of
a package still build.
Haskell member

/cc @kosmikus


I'm not sure if I'd not just use preferLatestOrdering v2 v1 here.

More importantly, however, I think you might want to decide whether you want `mappend` preferInstalledOrdering v1 v2 or `mappend` preferInstalledOrdering v2 v1. What do you want to do if there are multiple instances of the oldest version available, some installed, one not? I'm not sure myself (see additional comments in the pull request), but if you omit it, then it's essentially random.


As I said above, I'm not sure if it's worth having both preferLatestOrdering and preferOldestOrdering as separate functions.


Similar as in the modular solver. Do you really want to ignore isPreferred in this case?

I'll add the isPreferred here, because that is probably best. It allows for expressing: "I want all lower bounds except..". There will be exceptions for for example template haskell which is tied to compiler versions. There are other packages like this in base as well.


I'd prefer a different layout:

if      upgradeDeps then PreferAllLatest
else if oldestDeps  then PreferAllOldest
                    else PreferLatestForSelected

Ok. Generally, it looks good, and I'd support adding this. I'm not exactly sure what the semantics of this should be in corner cases, and I guess it somewhat depends on what's most useful. Is your "prefer oldest versions everywhere" really what you want as a package author? Would you not rather just "prefer oldest versions for my package"?

Preferring oldest versions recursively and everywhere is likely to run into problems for problematic lower bounds in completely different packages, thereby preventing you from actually checking whether your lower bounds are correct.

I'm also unsure about the interaction with other preference constraints (seems you're ignoring them in the topdown solver, but not in the modular solver because they're handled completely independently there). And about the interaction with preferring installed packages or not. If you take the "recursive and everywhere" viewpoint, you probably want to prefer source packages over installed packages, too. Because picking an installed package might implicitly pick "later" versions of transitive dependencies, whatever your installed package is built against. If you take the "local" viewpoint, then I think you want to prefer installed packages as usual, as that saves you rebuilding work.


My initial idea was to support the "recursive and everywhere" strategy, but I think your "local" version would indeed be more useful: picking an installed package when it is available.

I tried to build some of the packages of Haskell platform with the --oldest-deps flag but they all failed because some lower bounds weren't set. Thus at this point it would be good if those can be installed separately with working constraints and the testing is limited to the local dependencies.

The "recursive and everywhere" behaviour can always be simulated by making a fresh package database.


@craffit Well, you're just confirming my suspicions. So I think I'd actually prefer a really local implementation of this feature. I.e., the solver would prefer the oldest versions only for top-level goals, and have normal behaviour everywhere else.


I think I would say "Pick the oldest version for all dependencies. Useful for testing version ranges."

I don't really think of it as debugging as such (and stylistically, I think two separate sentences is more consistent with what is already there)


Wait, do we really want to prefer installed versions? I'm thinking as a package author, I'll have some release of my new package that I want to test.

  • I'll install it once normally, first. Probably just using cabal install without any options. This will pull in the latest compatible version of all dependencies.
  • I'll want to build it with all the old dependencies instead. Probably I don't want to install it like this. So I want to run cabal install --only-dependencies --older-dependencies or whatever, then cabal configure --older-dependencies, cabal build. Does that sound right? How is the first command going to behave if we're preferring installed versions, and I already have the latest versions of all of my deps?

Yeah I agree, would be most useful if it picked the oldest versions of all direct dependencies. Not a problem if you do a sandboxed build though.

Haskell member

Is anyone interested in pushing this change through competition? There seems to be some design issues to agree on first.

Haskell member

What's the status of this? If someone is interested in pushing it through completion that would be great. Otherwise I'll close this in the next few days. The code pull request will still be on GitHub if someone decides to pick it up later.

nh2 commented Oct 3, 2014

@craffit Are you up for this?

Haskell member

I'm closing this as there has been no progress for over a year. The pull request will still be around if anyone wants to pick it up later.

@ttuegel ttuegel closed this Sep 20, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment