Haskell Stack package installation error - haskell

user$: stack install dictionaries
Error: While constructing the build plan, the following exceptions were encountered:
In the dependencies for dictionaries-0.1.0.0:
binary-0.8.3.0 must match >=0.7.5 && <0.8 (latest applicable is 0.7.6.1)
time-1.6.0.1 must match >=1.5.0 && <1.6 (latest applicable is 1.5.0.1)
With the above command, I want to install the dictionaries package globally.
What are my options here?
I plan to stack unpack dictionaries, and then modify the versions.
But then how to install the modified 'local' package globally?
What's the best practices here?
Thanks

Easiest one: Add allow-newer: true to stack.yaml
It would to be the solution in this case. It solves the upper version limitation problem like yours. But of course there is possibility of build failure.
Maybe possible one: Change resolver to latest nightly
That failure occurs sometimes on nightly snapshot. And usually repaired soon by library update and new nightly snapshot. If you are using old snapshot, change it to latest. Or waiting may be one of solution.
Most general one: Make dependency to modified local package
You can do it by adding the package path to stack.yaml packages:. Then stack will use it instead of snapshot one.
The way you want is probably not a good idea. Even if that's possible, how are you going to handle with the many version of snapshot case? Local dependencies should be specified to each package.

With the above command, I want to install the dictionaries package globally.
(Preliminary note: by "globally", I will assume you mean globally for your user, as opposed to a system-wide installation.)
dictionaries is not in any Stackage snapshot. As far as I'm aware of, that means you cannot install it globally, as for libraries that is only an option if the package is in a snapshot. Cf. Stack issue #2656 -- while the planned feature described there sounds like what you are trying to do, there is a caveat:
Should also warn when it isn't used with --copy-bins, and if there are targets that don't have executables, as these both indicate a misunderstanding about how it works.
That being so, my suggestion is to install the package per-project, using the packages field with an extra-dep key -- that is, the "most general" solution in jeiea's answer.

Related

What does 'no specified version' mean in my Cabal build?

The recent Travis CI build of the development version of my Haskell package reports the error
MissingH must match >=1.3.0.1, but the stack configuration has no specified version (latest matching version is 1.4.0.1)
when building for GHC 8.6.1, even though I have
MissingH >=1.3.0.1
in my build-depends.
I don't understand this error: it seems contradictory. I have no upper limit on MissingH, so why is it erroring and not using the latest?
You need to add MissingH to stack.yaml.
extra-deps:
- 'MissingH-1.4.0.1'
Your package's *.cabal file says what versions of dependencies are compatible with your package. It is a loose specification, not all combinations may actually work (because they may have conflicting bounds on transitive dependencies, or there is some unforeseen breakage with a particular version you haven't tested with).
In contrast, stack.yaml describes a particular snapshot of packages, pinned to specific versions. This precisely says "my package is known to work with those versions". Of course, it is tedious to maintain the version of every dependency, and for that the Stackage team maintains a "resolver", a curated set of package versions known to work together, that you can use to specify the version of many packages at once, by setting the resolver: field of stack.yaml appropriately. A resolver only lists a subset of packages on Hackage, so when one of your dependencies is not in there, you need to add it to your stack.yaml as an extra-dep.
Update: following the discussion, some more details about configuring travis are necessary.
First, my current preferred solution for CI of Haskell projects is to not bother with stack and use instead https://github.com/haskell-CI/haskell-ci which generates a travis script using cabal-install.
Now for a less radical solution.
Currently the travis script is only varying the --resolver option, but as far as I can tell there is no command line option to add an extra-dep. It seems stack.yaml files are the only way for that. Furthermore, we only want to specify MissingH as an extra-dep for the latest nightlies, because LTS'es already include it.
Thus I suggest the following:
Create a separate stack.yaml for the nightly resolver only, call it something else since you already have one, for example stack-nightly.yaml
packages:
- .
extra-deps:
- 'MissingH-1.4.0.1'
Set an environment variable to point to stack-nightly.yaml when the resolver is a nightly, maybe:
env:
...
- $RESOLVER=nightly STACK_YAML=stack-nightly.yaml
# Not sure of the syntax.
Otherwise you can use the --stack-yaml command line option.

Recommended approach to use Stack as global package manager

I would like to install some Haskell libraries globally, for example hindent which is used by my editor's Haskell integration. What is the recommended way to do this?
I thought that stack install hindent was the correct way to do this. However, then I wanted to update my packages and found that there was no way to do this. According to the GitHub issue report I found,
stack is concerned with managing a local build sandbox for a project. It isn't intended to be a global package manager.
There appear to be workarounds such as maintaining a dummy project with artificial dependencies on the packages I would like installed. This sounds like a terrible hack, and I have been unable to find any official documentation on what approach should actually be taken.
Installing Haskell packages using my system package manager (Homebrew) is not an option since they are not packaged.
I would have opened an issue report against Stack, however the contribution guidelines requested that I instead ask a question here under the haskell-stack tag.
Well, stack install in any project will install to ~/.local/bin therefore making whatever executable you install be globally accessible.
The global project is used when running stack without a project, it is located in ~/.stack/global-project/stack.yaml.
If you want all of your globally accessible tools to have the same dependencies (perhaps to ensure that the ghc version matches or something), then you could make a project intended to build all of these tools. It's up to you whether or not it is the "global project" - there's not much special about it, it's just a default if you run stack and aren't in a project.
In order to record "what haskell executables do I want installed globally", you might consider creating a shell file like
#!/bin/sh
stack install hindent
And then running this whenever you change the versions of the installed tools.
Also, for tools like intero that need to match the ghc version, you can do stack install --copy-compiler-tool intero, and it will be available on the PATH when stack is used with that ghc version.

Installing local package with Stack

Is it possible to install package from sources with something similar to stack build package-name? (latter works with packages on Stackage, but not with custom ones)
Um, stack build (within the source directory)?
Stack doesn't really have a notion of installing libraries though, it only installs executables. To “install” locally-sourced packages, you need to specify what for you want them installed: add them as dependencies to another project, via a location: field in the packages: field in that project's stack.yaml file.
That's arguably sensible since, one might say, there's nothing you can do with an installed library except invoking it in another Haskell project (or in a REPL, which you can get with stack ghci). I personally don't hold with that though, I like actually being able to say install that library now. Which is one of the reasons I have always stuck to good old cabal-install rather than Stack. With that, you can just
cabal install
from within the source directory.
Cabal-install has often been criticised: its local installs can easily get out of sync and then you have weird dependency conflicts and need to rebuild lots of stuff. I never found this that much of a problem, and anyway this has been adressed in recent Cabal through Nix-style builds, which never produce conflicts.

Stackage inclusive or exclusive usage

I'm attempting to start a new project using the Snap web framework. I used snap init to get my basic skeleton working. I also put http://www.stackage.org/lts/cabal.config next to my .cabal file. I didn't uncomment the line to use Stackage exclusively. So I tried to build and it failed and couldn't find the version of lens required by my .cabal file. The cabal.config file from Stackage specifies a version of lens that is not the same as the one in my .cabal file. So I deleted every constraint from my package list and did the usual cabal install --only-dep -j8 --enable-test and it worked!
However, I have always been told that package versions should be constrained. So when working with Stackage is it okay to leave package versions unconstrained? Should I downgrade my packages to the ones available in Stackage instead?
As far as I understand a cabal.config file specifies a set of dependencies with the specific versions that satisfy dependencies, so how does Stackage work? Is it just a subset of packages from Hackage that are proven to be compatible? Do they host their own packages or rely on Hackage for downloads?
Thanks in advance :)
Both options are available. The default option is what you did, and still goes to hackage to get the packages. You just added a filter to your cabal that prevents you from using any version of a package included in Stackage that was not tested to work together with all of the other packages.
The other option is to simply point your cabal repo to a Stackage url, and then you will download packages directly from the Stackage server. That server will only serve packages that are known to work together, so there is no need for additional constraints in your cabal file. I actually prefer this way of working.
In both cases, if you have additional constraints in your cabal file that are incompatible with the Stackage restrictions, your build will fail. If you use the first option, you will get dependency conflicts. When using the second option, the Stackage server will simply report that it does not have that specific package/version.

How can I resolve zlib-enum, zlib-binding, zlib-conduit conflict when installing Yesod

I am trying to install my Yesod web app on another machine.
I have it installed fine on my current machine and can cabal install it on there without any problems.
I seem to run into trouble with it on the other machine though (which is a fresh Ubuntu VM - e.g., no cabal packages where installed on it prior.
Note that I changed nothing about my setup (e.g. cabal files are exactly the same).
This is the error I keep getting:
cabal: cannot configure zlib-enum-0.2.2. It requires zlib-bindings ==0.1.*
For the dependency on zlib-bindings ==0.1.* there are these packages:
zlib-bindings-0.1.0 and zlib-bindings-0.1.0.1. However none of them are available.
zlib-bindings-0.1.0 was excluded because zlib-conduit-0.2.0.1 requires zlib-bindings >=0.0.3 && <0.1
zlib-bindings-0.1.0 was excluded because zlib-bindings-0.0.3.2 was selected instead
zlib-bindings-0.1.0 was excluded because of the top level dependency zlib-bindings ==0.0.3.2
zlib-bindings-0.1.0.1 was excluded because zlib-conduit-0.2.0.1 requires zlib-bindings >=0.0.3 && <0.1
zlib-bindings-0.1.0.1 was excluded because zlib-bindings-0.0.3.2 was selected instead
zlib-bindings-0.1.0.1 was excluded because of the top level dependency zlib-bindings ==0.0.3.2
I have tried all kind of ways to resolve this, but keep running into this same problem, no matter what path I take.
My guess is, that theses packages' versions are conflicting at this point.
How can I resolve this until it gets fixed?
This is a prime example of cabal dependency hell. Theoretically, the fault lies with zlib-enum, since it should have had a major version bump to reflect the major version bump with zlib-bindings. But really, the problem is cabal's dependency analyzer. The new one will hopefully be ready soon.
In the meanwhile, depending on zlib-enum <= 0.2.1 should work.
Also, #ehird's answer should be helpful too, though it may not entirely solve the problem.
You might want to try installing the new Yesod Platform (Hackage page):
cabal install yesod-platform
It's a metapackage that depends on specific versions of Yesod and all its dependencies, designed to avoid versioning conflicts like this.
You could also try the in-development version of cabal-install, which has the modular dependency solver Michael mentioned. If you darcs get --lazy http://darcs.haskell.org/cabal/, you should be able to run bootstrap.sh in cabal/cabal-install to install it (but you should probably wipe ~/.cabal and ~/.ghc first).1 You still have to explicitly request the modular solver by passing --solver=modular to cabal, though.
Note that, even though it's a development version, it's actually pretty stable; lots of people on GHC 7.4.1 (including me) use it, since the version on Hackage doesn't compile. I haven't had any issues so far.
1 This is for Linux; I think the relevant directory is ~/Library/Haskell on OS X. I have no idea what to do on Windows, especially since the shell script won't run there.

Resources