How to actually use already-installed versions of a package, or find out why it's not possible?

248 Views Asked by At

Cabal-newstyle has a habit to occasionally install, like, all dependencies from scratch for no apparent reason. For a project using lens and other common packages, this can take upwards of ½ hour, which is annoying especially when the purpose is just to quickly compile a small change to an executable that built fine only a month ago.

Cabal does offer the option to specify as a constraint that a version of, say, lens that's already installed globally should be used. However, whenever I try that I just get

$ cabal new-run --constraint 'lens installed'
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: my-example-project-0.1.0.0 (user goal)
[__1] next goal: lens (dependency of dat103-Justus-lectures)
[__1] rejecting: lens-5.2, lens-5.1.1, lens-5.1, lens-5.0.1, lens-5,
lens-4.19.2, lens-4.19.1, lens-4.19, lens-4.18.1, lens-4.18, lens-4.17.1,
lens-4.17, lens-4.16.1, lens-4.16, lens-4.15.4, lens-4.15.3, lens-4.15.2,
lens-4.15.1, lens-4.15, lens-4.14, lens-4.13.2.1, lens-4.13.2, lens-4.13.1,
...
lens-0.4, lens-0.3, lens-0.2, lens-0.1 (constraint from command line flag
requires installed instance)
[__1] fail (backjumping, conflict set: my-example-project, lens)
After searching the rest of the dependency tree exhaustively

This is in spite of the fact that plenty of lens versions can be found in

$ ls -d ~/.cabal/store/ghc-8.6.4/lens*
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-1392f624ae052009275d5902a574e3f1804a66406a28222f0221cc2211da4f78
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-4854f213f63b67c0e1ea871303590def7a79bce4cc742f658e41dc4c76b56022
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-4caff99c8da3869df1dcfb67181d1be33d98316c3f458f93caedae05279c15e5
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-76531bf275303c15a9e6ae5160ca29f8fb15782d230b2576724103d67a4020d9
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-76a66d74e9cb85066009b345289db97d78bcf441beb12e6b762eb4d197000f19
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-813faecc9a5593fc14ef1677e82b9b384b66de9fff7843635cd7f4e5f4993d16
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-8c724c6d1fcc65ea38dc13fde30d86c4856151b235ef63628b23cee76d2feac5
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-90ec9224b09b828c948a6a1a310a085edc28f92a269bb839a2ac575dc60d579a
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-a157954a3d903fbf6444c054f9b704cab3fc23b36debc16fdc9ee8c0f5c0d5bd
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-c3bf086b6e081a91c7085b3c645652de0c4097edc4c88069203c5f741b14b97f
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-d5dca17dd7dddf6f324313f363ef74ff15d5717011dd750f415ce39942fc703b
/home/js/.cabal/store/ghc-8.6.4/lens-4.19.2-e4a1a8c9f3867cc6e6dc4dc059cc7fc0e4912d9aa4ce5476f63cdea9d3c8535e
/home/js/.cabal/store/ghc-8.6.4/lens-5.0.1-0956efd5ac393e6034c76c4dcc30a40ad1b12ad2b7a708e0f980648bac6287f3
/home/js/.cabal/store/ghc-8.6.4/lens-5.0.1-bfba2b0d59ebb884a2f32a960694c0e44af4fd29a21d8021ebdc42ce994fd055
/home/js/.cabal/store/ghc-8.6.4/lens-5.0.1-ce6c5a7496a674d60f93fae50caa4eb58acc26c6536937cce0f5243238cd6215
/home/js/.cabal/store/ghc-8.6.4/lens-5.0.1-d951ac24c700a8ae7f708a46a084e8fb4b0b008af29e5527f4d8986399248c62
/home/js/.cabal/store/ghc-8.6.4/lens-5.1-08384468083ebbc9d39619bfb59a32b97333acbf703c24bcf3b0bd22357a0115
...

So why are these not used? How to find out what Cabal even considers an “installed version”, and how to prevent that an installed version stops being usable?

1

There are 1 best solutions below

2
On

As mentioned in the comments, creating a "freeze file" using cabal freeze is a way to avoid "update churn":

cabal freeze writes out a freeze file which records all of the versions and flags that are picked by the solver under the current index and flags.

What if you didn't create such a file back in the day, how to avoid update churn now? cabal freeze seems to support the following command-line option:

 --index-state=STATE            Use source package index state as it existed
                                at a previous time. Accepts unix-timestamps
                                (e.g. '@1474732068'), ISO8601 UTC timestamps
                                (e.g. '2016-09-24T17:47:48Z'), or 'HEAD'
                                (default: 'HEAD').

So you could supply a date of around a month ago, and hopefully the freeze file will be generated without taking into account any versions of the project's dependencies released after that date.