Home > Software design >  Installing a Haskell program like `hackage-cli`
Installing a Haskell program like `hackage-cli`

Time:02-15

I would to install this program

https://github.com/hackage-trustees/hackage-cli

What is the simple way to do so ?

If I try to build it locally with

> cabal --version 
cabal-install version 3.4.1.0 
compiled using version 3.4.1.0 of the Cabal library)

I get

 ❯ cabal v1-build
Resolving dependencies...
Warning: solver failed to find a solution:
Could not resolve dependencies:
[__0] trying: hackage-cli-0.1.0.0 (user goal)
[__1] next goal: base (dependency of hackage-cli)
[__1] rejecting: base-4.15.1.0/installed-4.15.1.0 (conflict: hackage-cli =>
base>=4.10.0.0 && <4.13)
[__1] fail (backjumping, conflict set: base, hackage-cli)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: hackage-cli, base
Trying configure anyway.
Configuring hackage-cli-0.1.0.0...
cabal: Encountered missing or private dependencies:
Cabal >=2.4.1.0 && <2.5,
aeson >=1.4.2.0 && <2.1,
base >=4.10.0.0 && <4.13,
http-io-streams >=0.1.0.0 && <0.2,
io-streams >=1.5.0.1 && <1.6,
lens >=4.17 && <5.2,
netrc >=0.2.0.0 && <0.3,
optparse-applicative >=0.14 && <0.17,
process-extras >=0.7.4 && <0.8,
semigroups >=0.18.3 && <0.21,
stringsearch >=0.3.6 && <0.4,
tagsoup >=0.14 && <0.15,
tar >=0.5 && <0.6,
unordered-containers >=0.2.7 && <0.3,
zlib >=0.6.1 && <0.7

.

❯ cabal v2-build
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: hackage-cli-0.1.0.0 (user goal)
[__1] next goal: base (dependency of hackage-cli)
[__1] rejecting: base-4.15.1.0/installed-4.15.1.0 (conflict: hackage-cli =>
base>=4.10.0.0 && <4.13)
[__1] skipping: base-4.16.0.0, base-4.15.1.0, base-4.15.0.0, base-4.14.3.0,
base-4.14.2.0, base-4.14.1.0, base-4.14.0.0, base-4.13.0.0 (has the same
characteristics that caused the previous version to fail: excluded by
constraint '>=4.10.0.0 && <4.13' from 'hackage-cli')
[__1] rejecting: base-4.12.0.0, base-4.11.1.0, base-4.11.0.0, base-4.10.1.0,
base-4.10.0.0, base-4.9.1.0, base-4.9.0.0, base-4.8.2.0, base-4.8.1.0,
base-4.8.0.0, base-4.7.0.2, base-4.7.0.1, base-4.7.0.0, base-4.6.0.1,
base-4.6.0.0, base-4.5.1.0, base-4.5.0.0, base-4.4.1.0, base-4.4.0.0,
base-4.3.1.0, base-4.3.0.0, base-4.2.0.2, base-4.2.0.1, base-4.2.0.0,
base-4.1.0.0, base-4.0.0.0, base-3.0.3.2, base-3.0.3.1 (constraint from
non-upgradeable package requires installed instance)
[__1] fail (backjumping, conflict set: base, hackage-cli)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: base, hackage-cli

.

❯ stack init
Looking for .cabal or package.yaml files to use to init the project.
Using cabal packages:
- ./
- fixtures/

Multiple .cabal files found in directory /Users/nrolland/clones/hackage-cli/fixtures/:
- SVGFonts.2.cabal
- SVGFonts.0.cabal
- SVGFonts.1.cabal
- deepseq.1.cabal
- tree-diff.1.cabal
- semigroups.2.cabal
- semigroups.0.cabal
- tree-diff.0.cabal
- deepseq.0.cabal
- semigroups.1.cabal

CodePudding user response:

Short answer

A solution is below. Alternatively, you can clone from:

https://github.com/kabuhr/hackage-cli

to get a stack build-ready version. Note that you may need to apt install libbrotli-dev or similar before stack build.

Long answer

Here, stack init is being fooled by some extra .cabal files in the fixtures subdirectory. You can get around this by running stack init --ignore-subdirs. This ends up selecting resolver lts-14.27 but then fails because http-io-streams isn't in Stackage:

Selected resolver: https://raw.githubusercontent.com/
        commercialhaskell/stackage-snapshots/master/lts/14/27.yaml
Resolver 'https://raw.githubusercontent.com/commercialhaskell/
        stackage-snapshots/master/lts/14/27.yaml' does not have all
        the packages to match your requirements.
    http-io-streams not found
        - hackage-cli requires ^>=0.1.0.0

You can run:

stack init --resolver lts-14.27 --ignore-subdirs --omit-packages

to generate a stack.yaml anyway, and then add some extra-deps for http-io-streams and whatever it depends on. After a little fiddling, I came up with the following stack.yaml:

resolver: lts-14.27

packages:
- .

extra-deps:
- http-io-streams-0.1.2.0
- brotli-streams-0.0.0.0
- brotli-0.0.0.0

One additional patch is needed because the code to support versions of aeson earlier than 2.0.0.0 is broken. Apply the following patch:

diff --git a/src/IndexShaSum.hs b/src/IndexShaSum.hs
index 0296dff..bdfc4df 100644
--- a/src/IndexShaSum.hs
    b/src/IndexShaSum.hs
@@ -35,14  35,15 @@ import           Data.Semigroup         ((<>))
 #if MIN_VERSION_aeson(2,0,0)
 import qualified Data.Aeson.Key         as Key
 import qualified Data.Aeson.KeyMap      as KeyMap
 type Key = J.Key
 
-keyToText :: J.Key -> Text
 keyToText :: Key -> Text
 keyToText = Key.toText
 #else
 import qualified Data.HashMap.Strict    as KeyMap
 type Key = Text
 
-keyToText :: J.Key -> Text
 keyToText :: Key -> Text
 keyToText = id
 #endif
 
@@ -139,7  140,7 @@ decodePkgJsonFile bs = do
         go2 m = forM (KeyMap.toList m) $ \(k,v) -> do
             J.withObject ".targets{}" (go3 k) v
 
-        go3 :: J.Key -> J.Object -> J.Parser (ByteString, ByteString)
         go3 :: Key -> J.Object -> J.Parser (ByteString, ByteString)
         go3 k o = do
             hashes <- o J..: "hashes"
             sh256 <- hashes J..: "sha256"

With that patch applied, and the stack.yaml in place, you should be able to run stack build. If you get an error about building package brotli, you'll probably need development files for the brotli library installed (e.g., apt install libbrotli-dev on Debian flavors).

  • Related