Visitar URL original
Upgrading packages using v2-install --lib · Issue #7373 · haskell/cabal · GitHub
Skip to content

Upgrading packages using v2-install --lib #7373

Closed

Description

@rudymatela

Cabal refuses to install packages on the default environment (a.k.a. "user-wide") if there is an older version of a dependency installed.

Reproducing

Here is an example of how to reproduce:

$ rm -rf ~/.cabal ~/.ghc  # start fresh

$ cabal v2-install leancheck-0.9.1 --lib
Installing   leancheck-0.9.1 (lib)

$ cabal v2-install code-conjure --lib
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: code-conjure-0.0.4 (user goal)
[__1] next goal: leancheck (user goal)
[__1] rejecting: leancheck-0.9.4,
leancheck-0.9.3/installed-1sKCvqTVi3M636RaP3sUTx, leancheck-0.9.3,
leancheck-0.9.2 (constraint from user target requires ==0.9.1)
[__1] rejecting: leancheck-0.9.1 (conflict: code-conjure => leancheck>=0.9.4)
[__1] skipping: leancheck-0.9.0, leancheck-0.8.0, leancheck-0.7.7,
leancheck-0.7.6, leancheck-0.7.5, leancheck-0.7.4, leancheck-0.7.3,
leancheck-0.7.2, leancheck-0.7.1, leancheck-0.7.0, leancheck-0.6.7,
leancheck-0.6.6, leancheck-0.6.5, leancheck-0.6.4, leancheck-0.6.3,
leancheck-0.6.2, leancheck-0.6.1, leancheck-0.6.0, leancheck-0.5.0,
leancheck-0.4.1, leancheck-0.4.0, leancheck-0.3.0 (has the same
characteristics that caused the previous version to fail: excluded by
constraint '>=0.9.4' from 'code-conjure')
[__1] fail (backjumping, conflict set: code-conjure, leancheck)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: leancheck, code-conjure

Note: code-conjure v0.0.4 requires leancheck >= v0.9.4

The above simulates someone installing leancheck several months back (while v0.9.1 was the latest) then nowadays trying to install a package that depends on a newer version of leancheck.

This happens with other packages as well, see:

$ cabal v2-install QuickCheck-2.14 --lib
Installing   QuickCheck-2.14 (lib)

$ cabal v2-install quickcheck-instances-0.3.25.2 --lib  # latest version
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] next goal: QuickCheck (user goal)
[__0] rejecting: QuickCheck-2.14.2/installed-IqL8Pekwyon8v1lNoFQeCa,
QuickCheck-2.14.2, QuickCheck-2.14.1 (constraint from user target requires
==2.14)
[__0] trying: QuickCheck-2.14
[__1] next goal: quickcheck-instances (user goal)
[__1] rejecting: quickcheck-instances-0.3.25.2 (conflict: QuickCheck==2.14,
quickcheck-instances => QuickCheck>=2.14.1 && <2.14.3)
[__1] skipping: quickcheck-instances-0.3.25.1, quickcheck-instances-0.3.25,
quickcheck-instances-0.3.24 (has the same characteristics that caused the
previous version to fail: excludes 'QuickCheck' version 2.14)
[__1] rejecting: quickcheck-instances-0.3.23, quickcheck-instances-0.3.22,
quickcheck-instances-0.3.21, quickcheck-instances-0.3.20,
quickcheck-instances-0.3.19, quickcheck-instances-0.3.18,
quickcheck-instances-0.3.17, quickcheck-instances-0.3.16.1,
quickcheck-instances-0.3.16, quickcheck-instances-0.3.15,
quickcheck-instances-0.3.14, quickcheck-instances-0.3.13,
quickcheck-instances-0.3.12, quickcheck-instances-0.3.11,
quickcheck-instances-0.3.10, quickcheck-instances-0.3.9,
quickcheck-instances-0.3.8, quickcheck-instances-0.3.7,
quickcheck-instances-0.3.6, quickcheck-instances-0.3.5,
quickcheck-instances-0.3.4, quickcheck-instances-0.3.3,
quickcheck-instances-0.3.2, quickcheck-instances-0.3.1,
quickcheck-instances-0.3.0, quickcheck-instances-0.2.0,
quickcheck-instances-0.1.0 (constraint from user target requires ==0.3.25.2)
[__1] fail (backjumping, conflict set: QuickCheck, quickcheck-instances)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: quickcheck-instances, QuickCheck

Expected behaviour?

Is this expected behaviour?

I would expect what v1-install does: please install the latest version of this packages and upgrade any dependencies as required. This is not what happens in the current version.

If this is expected behaviour, that's fine. However, what should I do when I want to install the latest version while upgrading dependencies? Here is what I tried:

Forcing the upgrade of leancheck:

$ cabal v2-install leancheck --lib
Resolving dependencies...
Up to date

Not up to date. The installed version is 0.9.1 and the latest is 0.9.4. But okay maybe the above means install any version of leancheck, that is kind of up to date.

Let's try forcing the version:

$ cabal v2-install leancheck-0.9.4 --lib
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] next goal: leancheck (user goal)
[__0] rejecting: leancheck-0.9.4 (constraint from user target requires
==0.9.1)
[__0] rejecting: leancheck-0.9.3/installed-1sKCvqTVi3M636RaP3sUTx,
leancheck-0.9.3, leancheck-0.9.2, leancheck-0.9.1, leancheck-0.9.0,
leancheck-0.8.0, leancheck-0.7.7, leancheck-0.7.6, leancheck-0.7.5,
leancheck-0.7.4, leancheck-0.7.3, leancheck-0.7.2, leancheck-0.7.1,
leancheck-0.7.0, leancheck-0.6.7, leancheck-0.6.6, leancheck-0.6.5,
leancheck-0.6.4, leancheck-0.6.3, leancheck-0.6.2, leancheck-0.6.1,
leancheck-0.6.0, leancheck-0.5.0, leancheck-0.4.1, leancheck-0.4.0,
leancheck-0.3.0 (constraint from user target requires ==0.9.4)
[__0] fail (backjumping, conflict set: leancheck)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: leancheck

Does not work as well.

Let's try passing some extra flags:

$ cabal v2-install leancheck-0.9.4 --lib --shadow-installed-packages --upgrade-dependencies  --force-reinstalls --reinstall
...
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: leancheck

Let's try unregistering:

$ ghc-pkg unregister leancheck-0.9.1
ghc-pkg: cannot find package leancheck-0.9.1

At that point I gave up.

v1-install works

The thing is, I know how to solve this problem, the following three solutions work like a charm:

  1. nuke ~/.cabal and ~/.ghc folders:

    exec rm -rf ~/.cabal/{bin,lib,logs,share,store} ~/.ghc/*/
    

    Works every time.

  2. simply use v1-install to install my final package:

    $ cabal v1-install code-conjure
    Completed    express-0.1.6
    Completed    leancheck-0.9.4
    Completed    code-conjure-0.0.4
    
  3. upgrade my dependency with v1-install (then later install my package):

    $ cabal v1-install leancheck
    

However, these three solutions involve the legacy version of install or nuking config folders. I'm happy to do that, but I think these are confusing instructions to give to the users of my hackage packages. Is there a way to do what I want with v2-install? For instance, is there a way to do any of the following options:

  1. force upgrade when using cabal v2-install --lib <package>
  2. uninstall or unregister a package installed with cabal v2-install --lib <package>
  3. clear my user's "default" package env using cabal clear-package-env

System information

  • I'm on Arch Linux, but some of my users reported these same problems on Ubuntu.
  • GHC 8.10.4
  • Cabal 3.2.1.0
  • cabal-install 3.2.0.0

Activity

  1. rudymatela commented on Apr 28, 2021

    @rudymatela
    ContributorAuthor

    Some relevant use cases

    This wiki page about Cabal packages says: "While it is possible to "install" a library package "globally" it is most certainly a bad idea."

    I understand the "proper" way to use cabal is to create cabal project with a <myproject>.cabal file. Then cabal v2-* suite will take care of installing dependencies in sandboxes/package environments and users won't need to worry about which packages are installed or exposed. In this specific instance, v2-* work like a charm.

    However, here is an alternative use case:

    User "John Doe" wants to make a quick script to print a few enumerated pairs of numbers, he can just do:

    $ cabal install leancheck --lib
    ...
    $ cat > print.hs
    import Test.LeanCheck
    main  =  putStr . unlines . map show $ take 20 (list :: [(Int,Int)])
    ^D
    $ runhaskell print.hs 
    (0,0)
    (0,1)
    (1,0)
    (0,-1)
    (1,1)
    (-1,0)
    (0,2)
    ...
    

    Having a way to install packages "globally-to-the-user" is interesting in this case. Making a full cabalized project just to print 20 pairs of integers seems to much.

    Another possibility is that "John Doe" is a student that needs to play on GHCi with a library pointed to by his lecturer:

    $ cabal install my-lecturer-lib --lib
    ...
    $ ghci
    > ...
    > ...
    

    In this case, having a way to install packages "globally-to-the-user" is also helpful.

    These use cases are possible with v1-install but sometimes hard to replicate on v2-install. But maybe I'm not using v2-install right... 🤔

  2. fgaz commented on Apr 28, 2021

    @fgaz
    Member

    Is this expected behaviour?

    More like known :-/ #5559 is the original issue

    I would expect what v1-install does: please install the latest version of this packages and upgrade any dependencies as required. This is not what happens in the current version.

    This appears simple but it isn't. What if there is another installed package that depends on the one you're trying to upgrade? You'll sooner or later break some package and will have to reinstall everything (the infamous "cabal hell" that happened with v1- commands)

    I agree with your second post, and there is a more or less ongoing effort to replace v2-install --lib with a more principled cabal env command that can actually update environments: #6481

    There is a prototype linked in the OP of that issue, I encourage you to try it! It can handle all three examples you provided iirc.

  3. jneira commented on Jul 5, 2021

    @jneira
    Member

    @rudymatela agree with fgaz in a proper replacement for installing packages and make it available for ghc would be a new command cabal env.
    However you first use case, run a quick script with some package dependencies, could be achieved with the cabal scripting feature (example taken from the cabal reference):

    #!/usr/bin/env cabal
    {- cabal:
    build-depends: base ^>= 4.11
                , shelly ^>= 1.8.1
    -}
    
    main :: IO ()
    main = do
        ...

    executed with

    $ cabal v2-run script.hs
    $ cabal v2-run script.hs -- --arg1 # args are passed like this
    
  4. fgaz commented on Aug 28, 2021

    @fgaz
    Member

    Closing as duplicate of #5559

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions