Stack init package not found - haskell

When trying to build an existing project with Stack I got errors like
bv not found
- Genesis requires >=0.3 && <0.4 && -any
- exp requires -any
during stack init. The packages are all installed in a sandbox and are from hackage. I'm almost sure Stack doesn't look into the sandbox, but why can't it find the packages from hackage? I'm also able to build just by running cabal build.

stack does not look at Hackage at first. It tries to build your project using only packages from a snapshot of Stackage (you can find the exact snapshot you are using in the resolver field of stack.yaml). bv does not seem to be in Stackage (at least it is not in the latest LTS snapshot). Fortunately, the issue is easy to solve: just run stack solver --modify-stack-yaml. That will identify all non-Stackage dependencies and add them to the extra-deps field of stack.yaml. From that point on, those dependencies will be built somewhere in the .stack-work subdirectory of your project, in a very similar way to packages in a cabal-install sandbox.

Related

How do I instruct cabal-install or stack to use a local version of a hackage package?

Say I want to tinker with a few hackage packages that depend on each other and run
stack unpack foo-1.2.0
and
stack unpack bar-1.0.0
where bar depends on foo.
Now, to build my modified bar with my modified foo, I specify in my bar.cabal:
build-depends:
foo == 1.2.0
and add to my bar's stack.yaml:
packages:
- .
- rel/path/to/foo-1.2.0/
This works, and builds fine but it seems that if a dependency of bar, say some-package, itself depends on foo it will default to the hackage version rather than compile with my modified version despite my modified version meeting the version constraints. Is there a way to force other dependencies further up the chain to use my local version of the package during the build process? I appreciate this is a very unusual use case.
Weirdly I'm able to build fine but trying to load into stack ghci fails with:
Couldn't match type `foo-1.2.0:Some.Type.InFoo.aDataType`
with `aDataType`
NB: `aDataType` is defined at
`full/path/to/foo-1.2.0/Some/Type/InFoo.hs:(23,1)-(28-60)`
`foo-1.2.0:Some.Type.InFoo.aDataType`
is defined in `Some.Type.InFoo`
in package `foo-1.2.0`
Expected type: `aDataType`
Actual type: `foo-1.2.0:Some.Type.InFoo.aDataType`
According to the Cabal User Guide, when developing a project with several local packages:
Local packages, as well as the external packages [...] which depend
on them, are built inplace, meaning that they are always built
specifically for the project and are not installed globally.
So it seems that even external packages (that is, packages from Hackage or another package repository) will use the local packages, at the cost of needing to be rebuilt for the current project.

Stack: 'hdevtools is a library dependency, but the package provides no library needed since my-app is a build target.'

I was trying to add hdevtools to my stack project, so I ran stack build hdevtools. The install seemed to work successfully, and my text editor stopped reporting imported libraries installed via stack (like aeson and tasty) as missing.
However, things went wrong when I added this line to the dependencies section of my package.yaml file:
- hdevtools >= 0.1 && < 1
And then tried to run stack build again. I received the following error output:
Error: While constructing the build plan, the following exceptions were encountered:
In the dependencies for my-app-name-0.1.0.0:
hdevtools is a library dependency, but the package provides no library
needed since my-app-name is a build target.
Some different approaches to resolving this:
* Consider trying 'stack solver', which uses the cabal-install solver to attempt
to find some working build configuration. This can be convenient when dealing
with many complicated constraint errors, but results may be unpredictable.
Plan construction failed.
I tried running stack solver, but that threw the exception documented here.
How can I declare hdevtools as a dependency of my project?
#alexis-king recommends using stack build --copy-compiler-tool hdevtools in this guide, in the section titled Setting up editor integration.
This works for the current project, and other projects using the same GHC version, but you will need to run it again when you upgrade to a new GHC version.
More context from King's guide:
As mentioned above, stack install is not what you want. Tools like ghc-mod, hlint, hoogle, weeder, and intero work best when installed as part of the sandbox, not globally, since that ensures they will match the current GHC version your project is using.
How can I declare hdevtools as a dependency of my project?
hdevtool is an executable and cabal doesn't have a concept of development dependencies (like in other package managers like npm etc). So, all you can do is install hdevtools globally and make it work.

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.

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.

Create hackage package that can be installed with stack

When running stack sdist in my project directory, the stack.yaml file isn't included in the tarball (this seems to be expected).
Consequently, when I upload the tarball to hackage, then stack install mypackage it complains about missing dependencies (extra-deps) which I specified in the stack.yaml file.
$ stack install pandoc-placetable
Run from outside a project, using implicit global project config
Using resolver: lts-5.17 from implicit global project's config file: ~/.stack/global-project/stack.yaml
While constructing the BuildPlan the following exceptions were encountered:
-- Failure when adding dependencies:
spreadsheet: needed (>=0.1.3 && <0.1.4), not present in build plan (latest applicable is 0.1.3.4)
needed for package: pandoc-placetable-0.4
-- While attempting to add dependency,
Could not find package spreadsheet in known packages
Recommended action: try adding the following to your extra-deps in /Users/maurobieg/.stack/global-project/stack.yaml
- spreadsheet-0.1.3.4
Or what's the recommended way to make a hackage package stack-installable if it has further hackage dependencies?
Update: I just added extra-source-files: stack.yaml to the cabal file and the stack.yaml is indeed included in the tarbal of the newly published version. Nevertheless, stack install pandoc-placetable-0.4.1 still comes up with the same error.
I could also just tell people who don't want to install cabal-install on their system to clone from GitHub, then build with stack. Is that the recommended approach for tiny packages? Or should I ask them to include the dependency of pandoc-placetable (i.e. spreadsheet) in their global stack.yaml? Smells like polluting a global file...
As mentioned by #mgsloan in the comments above: There's an open stack issue about using stack.yaml from hackage package.
I guess until it's fixed I'll just tell people to clone from GitHub (or as mentioned by #MichaelSnoyman to stack unpack) and then cd into the newly created directory and stack install there.

Resources