Reputation: 16850
I find cabal
's behavior when installing packages maddening. For example, running
cabal install funsat
installed old versions of array
, time
, random
, quickcheck
, and bitset
, breaking packages like monadiccp
, hoogle
, heist
, snap
, etc.
It works to go back and cabal install monadiccp
, etc., but how can I avoid the default behavior of cabal breaking installed packages? Any reasonable Linux package manager, like aptitude
or zypper
would ask whether I wanted to break already installed packages, when installing a new package.
Has anyone cooked up a workaround script? Thanks in advance.
Upvotes: 5
Views: 461
Reputation: 15028
This is a known problem (see this slide deck, starting with slide 22). The Darcs version of cabal-install
(darcs get http://darcs.haskell.org/cabal
) now shows a warning when installing a package will break your system. Example:
$ cabal --version cabal-install version 0.13.3 using version 1.13.3 of the Cabal library $ cabal install monadiccp [...] $ cabal install funsat Resolving dependencies... In order, the following would be installed: mtl-1.1.1.1 (new version) syb-0.3.6 (new package) array-0.2.0.0 (new version) containers-0.2.0.1 (new version) bimap-0.2.4 (new package) deepseq-1.2.0.1 (reinstall) changes: array-0.3.0.2 -> 0.2.0.0 fgl-5.4.2.2 (new package) text-0.11.1.12 (reinstall) changes: array-0.3.0.2 -> 0.2.0.0 parsec-3.1.2 (reinstall) changes: mtl-2.0.1.0 -> 1.1.1.1 parse-dimacs-1.2 (new package) time-1.1.4 (new version) random-1.0.0.3 (reinstall) changes: time-1.2.0.3 -> 1.1.4 QuickCheck-1.2.0.1 -base3 (new package) bitset-0.6 (new package) funsat-0.6.1 (new package) cabal: The install plan contains reinstalls which can break your GHC installation. You can use the --avoid-reinstalls option to try to avoid this or try to ghc-pkg unregister the version of the package version to see its effect on reverse dependencies. If you know what you are doing you can use the --override-reinstall-check option to override this reinstall check.
Upvotes: 2
Reputation: 40787
I recommend cabal-dev, which maintains a separate set of installed packages for each project you work on. That doesn't solve the bad behaviour of cabal-install in general, but means that such failures are more isolated than they would otherwise be, and allows you to fix them more easily by simply doing cabal-dev clean && cabal-dev install
.
The added benefit of reproducible builds is also nice.
Admittedly, this isn't a workaround for your specific problem, but it lessens cabal-install pain in general.
Building on Daniel Fischer's answer, here's a wrapper for cabal
that aborts an installation if it would reinstall a package:
cabal () {
if [ "$1" = "install" ]; then
local out=$(command cabal --dry-run -v2 "$@" 2>&1)
if echo "$out" | egrep -c '\((reinstall|new version)\)' >/dev/null; then
echo "$out"
return 1
fi
fi
command cabal "$@"
}
YMMV; I've only lightly tested this and it causes an annoying delay at start-up as all the dependencies have to be calculated twice. But it should relieve some tedium if you want to stay on the safe side.
Upvotes: 8
Reputation: 183873
Workaround: always check with --dry-run
first. If cabal would reinstall any package, watch out.
Upvotes: 5