Stack won't resolve a 'hidden' dependency - haskell

I am working on my first major Haskell application, and want to add mockery to create disposable test WAI threads. Importing mockery and running stack test resulted in the compiler error:
Failed to load interface for ‘Test.Mockery.Directory’
It is a member of the hidden package ‘mockery-0.3.5’.
Perhaps you need to add ‘mockery’ to the build-depends in your .cabal file.
Use -v to see a list of the files searched for.
So, I added mockery to my cabal file under test dependencies. However, when I run stack build or stack test mockery is automatically removed from the cabal file.
I have also tried listing mockery-0.3.5 under extra-deps in the stack.yaml file. This unsurprisingly didn't work, since mockery is part of my lts, and extra deps is for packages outside of lts.
How can I get stack to recognize that mockery should be included as a dependency to to project?
Here is my stack.yaml:
flags: {}
ghc-options:
! '*': -Wall
packages:
- .
extra-deps: [
]
resolver: lts-9.5
I'm using stack version 1.5.1
I imagine this is a stupid build issue and look forward to confronting my obvious oversight.

In stack.yaml you declare the Stackage LTS version, a curated list of hackage dependencies that you want to depend on. You can also depend on local packages and packages in git that are not in Hackage. You may also change the versions of the packages in LTS as long as they respect the constraints of the other dependencies.
package.yaml is the build file. Any packages you want to import directly in your Haskell code must be declared in here as dependencies, even if they are explicitly declared in the stack.yaml.
Finally, when you see It is a member of the hidden package, that means that one of your dependencies is using that package, but it is not declared as a dependency in your build file.

Related

How do you import a Haskell module that was installed using Cabal?

I installed the timezone-series Haskell module using cabal install timezone-series-0.1.5.1.
I then defined a module named Main.hs that starts with:
import Data.Time.LocalTime.TimeZone.Series -- from timezone-series-0.1.5.1
when I run ghc Main.hs, GHC throws the following error:
/home/ubuntu/Main.hs:2:1: error:
Failed to load interface for ‘Data.Time.LocalTime.TimeZone.Olson’
I tried explicitly including the cabal directory in GHC's search path using:
ghc -i/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/ Main.hs
This resulted in the correct path being searched, but GHC is only looking for files ending in the suffix ".hs":
Locations searched:
...
/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/Data/Time/LocalTime/TimeZone/Series.hs
/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/Data/Time/LocalTime/TimeZone/Series.lhs
/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/Data/Time/LocalTime/TimeZone/Series.hsig
/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/Data/Time/LocalTime/TimeZone/Series.lhsig
Cabal installed interface files instead however:
/home/ubuntu/.cabal/lib/x86_64-linux-ghc-8.0.2/timezone-olson-0.2.0-KqRNJj3zomR7zz2Yx6P5Oq/Data/Time/LocalTime/TimeZone/Olson.hi
From line 318 of GHC's source code it looks like GHC ignores "*.hi" files unless it is called in single-shot mode (with the -c flag). Is this correct? (See: https://github.com/ghc/ghc/blob/67a5a91ef5e61f3b3c84481d8a396ed48cd5d96e/compiler/GHC/Unit/Finder.hs)
How can I get GHC to import this module?
An help will be greatly appreciated!
My suggested ways of installing packages in order of my preference:
Make a cabal package and add timezone-series you want to install to the build-depends field as described in the cabal manual.
Use the experimental cabal-env tool to basically automate the process of point 3 below, but then with the global environment. This makes a new build-plan every time you install a new package, so it is like removing the package environment and building it again with all the old packages and the new package added to it. You can add specific constraints like this: cabal-env "timezone-series == 0.1.5.1".
Install a package into local package environment with cabal --package-env . --lib timezone-series. You can add as many packages as you want after the --lib option to install more than one package. If you later want to use a different set of packages simply remove the .ghc.environment.* file that is generated and rerun the installation with a new set of packages. GHC will automatically use these package environment files that are in the current or parent directories. You can specify specific constraints with the --constraint option like this: --constraint "timezone-series == 0.1.5.1".
Use cabal install --lib timezone-series to install it directly into the global environment (~/.ghc/x86_64-linux-8.0.2/environments/default), this will fail if a conflicting package was installed earlier. When you run into errors you can remove that package environment and try again.
Finally, I want to note that GHC 8.0.2 is quite old, so I would advise you to upgrade if you don't have a specific reason for using that version.

Haskell dependency hell

I'm trying to include a specific version of a library in a Haskell project. The library is bed-and-breakfast (which is used for martix operations), but I need the specific version 0.4.3 which fixed a bug with the multiplication implementation.
So, my stack.yaml looks like this:
flags: {}
extra-package-dbs: []
packages:
- .
extra-deps:
- bed-and-breakfast-0.4
- base-4.6.0.1
resolver: lts-12.8
But I'm getting this error when building:
Error: While constructing the build plan, the following exceptions were encountered:
In the dependencies for bed-and-breakfast-0.4:
base-4.11.1.0 from stack configuration does not match >=4.5 && <4.7 (latest matching version
is 4.6.0.1)
needed due to realworldhaskell-0.1.0.0 -> bed-and-breakfast-0.4
Some different approaches to resolving this:
* Set 'allow-newer: true' to ignore all version constraints and build anyway.
* 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.
* Recommended action: try adding the following to your extra-deps
in C:\Users\info\Desktop\Projects\haskell\stack.yaml:
- base-4.6.0.1
I've done the recommended action but it didn't solve anything. I've tried using different resolvers to see if it's an issue with my GHCi version but nothings worked. What is the best way to interpret error messages like this and how should I proceed?
EDIT:
If I remove -base.4.6.0.1 and add allow-newer: true I get this:
WARNING: Ignoring out of range dependency (allow-newer enabled): base-4.11.1.0. bed-and-breakfast requires: >=4.5 && <4.7
bed-and-breakfast-0.4: configure
Progress 1/2
-- While building custom Setup.hs for package bed-and-breakfast-0.4 using:
C:\sr\setup-exe-cache\x86_64-windows\Cabal-simple_Z6RU0evB_2.2.0.1_ghc-8.4.3.exe --builddir=.stack-work\dist\7d103d30 configure --with-ghc=C:\Users\info\AppData\Local\Programs\stack\x86_64-windows\ghc-8.4.3\bin\ghc.EXE --with-g
hc-pkg=C:\Users\info\AppData\Local\Programs\stack\x86_64-windows\ghc-8.4.3\bin\ghc-pkg.EXE --user --package-db=clear --package-db=global --package-db=C:\sr\snapshots\76fd1958\pkgdb --package-db=C:\Users\info\Desktop\Projects\haskell\
.stack-work\install\8c390635\pkgdb --libdir=C:\Users\info\Desktop\Projects\haskell\.stack-work\install\8c390635\lib --bindir=C:\Users\info\Desktop\Projects\haskell\.stack-work\install\8c390635\bin --datadir=C:\Users\info\Desktop\Proj
ects\haskell\.stack-work\install\8c390635\share --libexecdir=C:\Users\info\Desktop\Projects\haskell\.stack-work\install\8c390635\libexec --sysconfdir=C:\Users\info\Desktop\Projects\haskell\.stack-work\install\8c390635\etc --docdir=C:
\Users\info\Desktop\Projects\haskell\.stack-work\install\8c390635\doc\bed-and-breakfast-0.4 --htmldir=C:\Users\info\Desktop\Projects\haskell\.stack-work\install\8c390635\doc\bed-and-breakfast-0.4 --haddockdir=C:\Users\info\Desktop\Pr
ojects\haskell\.stack-work\install\8c390635\doc\bed-and-breakfast-0.4 --dependency=array=array-0.5.2.0 --dependency=base=base-4.11.1.0 --dependency=binary=binary-0.8.5.1 --dependency=deepseq=deepseq-1.4.3.0 --dependency=template-hask
ell=template-haskell-2.13.0.0 --extra-include-dirs=C:\Users\info\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512\mingw64\include --extra-lib-dirs=C:\Users\info\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512\min
gw64\bin --extra-lib-dirs=C:\Users\info\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512\mingw64\lib --exact-configuration
Process exited with code: ExitFailure 1
Logs have been written to: C:\Users\info\Desktop\Projects\haskell\.stack-work\logs\bed-and-breakfast-0.4.log
Configuring bed-and-breakfast-0.4...
Cabal-simple_Z6RU0evB_2.2.0.1_ghc-8.4.3.exe: The package has an impossible
version range for a dependency on an internal library: bed-and-breakfast
==0.3.2. This version range does not include the current package, and must be
removed as the current package's library will always be used.
EDIT 2:
Ok, so I'm guessing that the bed-and-breakfast library needs base 4.11.1.0 which is included in GHCi 6.10.2 (according to https://wiki.haskell.org/Base_package) so I need a resolver which matches that GHCi version. Where can I find out what resolver version that is?
Here is the constraint on the latest available bed-and-breakfast package: base (>=4.5 && <4.7), which means it will likely not even compile with GHC version higher then 7.6. Considering that there is even no LTS snapshot prior to GHC 7.8, you are out of luck with that package.
To say it in another words, the package is outdated and your choices are:
submit an issue and hope maintainer will do something about it
try to make it work with newer ghc yourself
Use a different package

Is there a tool for upgrading the dependecies' upper bounds to the latest versions of each dependency?

I'm trying to upgrade the dependencies of the pipes-files package, so that it can be included in the latest stack LTS. The pipes-files package does not contain a stack.yaml file, and the pipes-files.cabal file contains quite some upper and lower bounds on its dependencies, e.g.:
base >=4.7 && <4.10
, transformers >=0.3 && <0.6
, transformers-base >=0.3 && <0.6
-- and quite some more ...
Is there a tool that I can run to get the latest versions of each of these dependencies? The closest thing I could find was packdeps but it will require me to search for the dependencies one by one.
Preliminary notes:
hierarchy, a dependency of pipes-files, has the same issue you are trying to work around -- it is not in Stackage and has version bounds outdated with respect to the latest LTS. That means you'll first have to get it to build successfully, and then add your tweaked version of it to the extra-deps in the stack.yaml of pipes-files.
cabal gen-bounds, which "suggest[s] dependency version bounds that conform to Package Versioning Policy", is, in principle, the right tool for the job. However, getting cabal-install to behave according to the restrictions of a Stack-centric environment is not always straightforward. While this seems enough to run cabal gen-bounds from a bash shell in the absence of a Stack-independent GHC installation...
PATH=$PATH:$(stack path --compiler-bin) cabal gen-bounds
... I couldn't figure out how to get it to follow the version restrictions of the Stack(age) snapshot -- in particular, the --package-db option, which can be helpful with commands such as cabal configure, doesn't seem to be accepted by gen-bounds.
As I don't know how to make cabal gen-bounds and Stack cooperate, I will suggest a somewhat more convoluted method, but one that doesn't require using cabal-install directly. It uses Jenga, a tool that can retrieve the version information left implicit by your choice of Stackage snapshot. Jenga is not on Stackage; to install it with Stack, grab the sources from GitHub (or with stack unpack jenga) and then run stack init --solver followed by stack install.
Remove all version bounds from the hierarchy.cabal file (or whatever the relevant .cabal file is).
stack init --solver, to create a stack.yaml file with any extra-deps that might be necessary. (You can use --resolver to explicitly choose the snapshot to be used.)
stack build, as a sanity check that the package is buildable.
In the generated stack.yaml, check whether the extra-deps field is commented out; if so, uncomment it. This is necessary for step #6 to work.
jenga -i hierarchy.cabal, which will print the exact dependency versions Stack would use to build the package.
Paste the versions Jenga gave you into the build-depends of the .cabal file, adjusting then if desired (at a minimum, you'll probably want to relax the minor version bounds for PVP compliance -- e.g. changing base == 4.9.1.0 to base == 4.9.*).

Despite stack solver, Could not find module `Test.Hspec'

This is my stack.yaml file declaring hspec as a extra dependency:
# Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2)
resolver: lts-3.8
# Local packages, usually specified by relative directory name
packages:
- '.'
# Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3)
extra-deps:
- hspec-2.2.0
when I run stack solver it says there is no change to be done:
root#5d7daa2aec0a:/src/test_stack/a-test/src# stack solver
This command is not guaranteed to give you a perfect build plan
It's possible that even with the changes generated below, you will still need to do some manual tweaking
Asking cabal to calculate a build plan, please wait
No needed changes found
To automatically modify your stack.yaml file, rerun with '--modify-stack-yaml'
this is my source file (only to check that I could use Hspec with stack):
module Main where
import Test.Hspec
main :: IO ()
main = do
putStrLn "hello world"
and when I run stack build I get:
2015-10-05 22:24:08.450413: [warn] Could not find module `Test.Hspec' #(stack_Bp003b8iWaELtdr693pSPs:Stack.Build.Execute src/Stack/Build/Execute.hs:1241:35)
I thought stack solver was ensuring that extra dependencies are ok.
What I am doing wrong ?
It's the first time I use stack.
While stack replaces cabal-install, the command line tool for building and installing packages, it still uses the Cabal packaging infrastructure. In particular, that means projects built with stack are still Cabal-compatible packages with .cabal files, and all of their dependencies should be listed in the build-depends section of the .cabal file with appropriate version ranges. That holds even if the dependency is also specified in the stack.yaml file extra-deps field, as that field serves a different purpose (namely, giving stack an exact version to use when building the package).

Difference between new-template.cabal and stack.yaml

I want to use reactive-banana in my new Haskell project. I never used cabal-install or stack before. I created a directory and initialized project files in it using stack new. I see now 2 files in the directory: new-template.cabal and stack.yaml.
How do I set dependencies and make sure they are downloaded and compiled?
At first I tried to add - reactive-banana-0.8.0.2 in stack.yaml under extra-deps:, but both stack build and stack solver didn't download it. Then I augmented a part called library in new-template.cabal to this:
library
hs-source-dirs: src
exposed-modules: Lib
build-depends: base >= 4.7 && < 5
, reactive-banana >= 0.8
default-language: Haskell2010
Every time I tried to run stack build, it crashed with an error and suggestion to add some package to stack.yaml under extra-deps:, and this happened three times until finally all packages installed, and I could import them in stack ghci REPL.
So my question is, what is the idiomatic way to use stack? Which of these 2 files should I use to specify dependencies and other project metadata? What is the sample workflow of an average Haskell developer with stack?
When using stack I generally don't put any versions bounds in my .cabal file. I let the resolver and extra-deps setting in the stack.yaml file determine which versions of packages to select.
Here is a stack.yaml file which brings in reactive-banana-0.8.1.2:
flags: {}
packages:
- '.'
extra-deps:
- reactive-banana-0.8.1.2
- psqueues-0.2.0.2
resolver: lts-2.17
In my .cabal file I just have:
build-depends: base >= 4.7 && < 5, reactive-banana
The reactive-banana version is pinned by the stack.yaml file.
If you want to use GHC 7.10 change the resolver to something like nightly-2015-06-17.
I determine the extra-deps iteratively, by just running stack build and adding whatever dependencies are missing to the stack.yaml file until all dependencies are satisfied.
You will only need to do this with packages which are not in Stackage - like reactive-banana. A great many of commonly used packages are in Stackage and their versions will be determined by the resolver setting.
In the default configuration, stack works with two package databases: a centralised per-user one and a project-specific one. The centralised database only pulls packages from Stackage, a subset of Hackage with known-to-be-compatible packages, while you can put whatever you want on the project-specific database. All packages you use must be in the cabal file, but those not on Stackage (that is, the ones that will go to the project-specific database) must also be listed in the extra-deps section of stack.yaml. reactive-banana is not on Stackage, so you need to add it to stack.yaml, like this:
# etc.
extra-deps:
- reactive-banana-0.8.1.2
# etc.
stack solver can fill in the extra dependencies in stack.yaml for you.

Resources