How to set up conditional dependency for Stack project? - haskell

I'm trying to enable my Stack-based Haskell project to apply a certain GHC plugin when the user requires it.
I have successfully added the -fplugin flags through the ghc-options. As far as I know I have to add the plugin package as a dependency in my package.yaml file. However I would like to configure the project so that the extra dependency is only added if the user requires it (with a flag set, environment variable or some other means).
I have tried to use the when keyword in the package.yaml to conditionally enable the dependency:
when:
- condition: flag(useplugin)
then:
dependencies: [ myplugin ]
else:
dependencies: []
However this results in an error coming from cabal:
- 0:0: These flags are used without having been defined: myplugin
I couldn't find the option for package.yaml which would generate the flag definition (like described here) in the generated cabal file.

Related

transformers-0.5.6.2 from stack configuration does not match >=0.3 && ==0.2.*

I'm trying to include quickcheck-instances package for testing. Here is how my dependencies field in package.yaml looks like:
dependencies:
- blackjack
- quickcheck-instances >= 0.3.25 && < 0.4
- QuickCheck >= 2.14.2 && < 2.15
Here is how my extra-deps field in stack.yaml looks like:
extra-deps:
- quickcheck-instances-0.3.25.2#sha256:083b84b91fccb3bbf22cd906f5bc731c8e6ee96c7554e892985452f2d61d4ad3,4484
- hashable-1.3.3.0#sha256:7f3b67151162a1dfe8472dc30430af98ed5470801d3f4b6c9b8d7a7443c920d4,4068
- unordered-containers-0.2.14.0#sha256:2fe789f78246b7c7ec10d7b85c72d898a9f72fdda5b60d581e839d21016bc628,4992
- QuickCheck-2.14.2#sha256:4ce29211223d5e6620ebceba34a3ca9ccf1c10c0cf387d48aea45599222ee5aa,7736
- case-insensitive-1.2.1.0#sha256:9dfd3171fc7698cf8d931727d3af3a7b389135b583e46b5adac1f9d2026fff61,2244
- data-fix-0.3.2#sha256:ca5ee8d5e15d08e65e9af74004cd663391706c0a62b7d1c6d0023e4c34cd0038,1659
- integer-logarithms-1.0.3.1#sha256:888fb6c4fbd79ed2e8f8b94b61bccac25f7fab2b13b32b496e86828bc60b17cf,3184
- old-time-1.1.0.3#sha256:c91fbb3ee73d20ccd015842b30f1f29a304893ebe0ae3128b7bbc13d5bb0d4c8,1328
- scientific-0.3.7.0#sha256:0f188a7b92780d81a2e3cf1195a3a24cfe3e7c43d0e9e0f2101a465803d68076,4773
- splitmix-0.1.0.3#sha256:fc3aae74c467f4b608050bef53aec17904a618731df9407e655d8f3bf8c32d5c,6049
- strict-0.4.0.1#sha256:50187e750751a258efea12ef2979e16a014a953c15bf4c2fca2f1168a44a5a12,4156
- tagged-0.8.6.1#sha256:29c67d98a4404607f024750ab9c7210dadcbbef4e1944c48c52902f2071b2662,2874
- these-1.1.1.1#sha256:bdc0a3015b2e5cdf016e402937d71856ae5fe4e9e9a0d4823cc94a214c55a39b,2732
- time-compat-1.9.6.1#sha256:cddf1a7654ccc3564d2197e6bf0064254abf792c591a9fa0eaa16e6039036152,4997
- uuid-types-1.0.5#sha256:5031383749d57cb95877d7e56f0300be66652b6e57f5ba6681dcc6e4f78d046d,2541
- vector-0.12.3.0#sha256:0ae2c1ba86f0077910be242ec6802cc3d7725fe7b2bea6987201aa3737b239b5,7953
- assoc-1.0.2#sha256:a824e4f615469a27ad949dbf4907ba258bd6b459deebec00524c7bcb3f65cc9f,1205
- base-orphans-0.8.5#sha256:b01baac1b88cc80e70214c064ec8c174718c19400232588bff591f5a9c49a750,3177
- old-locale-1.0.0.7#sha256:fa998be2c7e00cd26a6e9075bea790caaf3932caa3e9497ad69bc20380dd6911,1071
- primitive-0.7.2.0#sha256:d7c3635e83ae160129cdfe2be4092ab6389199d73a2c29adf904124dbcfe6100,2660
- random-1.2.0#sha256:195506fedaa7c31c1fa2a747e9b49b4a5d1f0b09dd8f1291f23a771656faeec3,6097
- bifunctors-5.5.11#sha256:cc425ee85aae56dba1123baf6fb3fa7abcd90782f26bb904eef14c7332ee85f6,3919
- comonad-5.0.8#sha256:1f1aabd73ec7f80f20cf078a748a60cd48d8e57277802fdf6a9ab3601a9b8f7e,3631
- th-abstraction-0.4.3.0#sha256:db4b3b69398acd8a7c5c8cc8a962da55d65d05d44d5039b51bd3cb5fb3d8400f,2148
- distributive-0.6.2.1#sha256:0f99f5541cca04acf89b64432b03422b6408e830a8dff30e6c4334ef1a48680c,2996
- indexed-traversable-0.1.1#sha256:e4602357513aa3b146546227732e6e5698392f4324ab690e109cc05676ba3b4f,2491
- transformers-compat-0.6.6#sha256:510709db2b12d1510d70de824ee544ca0a9e6f27aa7e299218cbacc0750b4a5e,5560
- transformers-0.5.6.2#sha256:6c959d14430f4deffb99579ba019de07c3d852a2122b6f449344386c7d75ff1d,3172
This is the error I got:
Error: While constructing the build plan, the following exceptions were encountered:
In the dependencies for transformers-compat-0.6.6:
transformers-0.5.6.2 from stack configuration does not match >=0.3 && ==0.2.*
needed due to blackjack-0.1.0.0 -> transformers-compat-0.6.6
Some different approaches to resolving this:
* Set 'allow-newer: true' in /home/xwtek/.stack/config.yaml to ignore all version constraints and build anyway.
Plan construction failed.
Of course after setting the allow-newer into true, it works, but I don't want to mess with that setting, because I fear that something like that would make things break later. Any better solution?
Clearly, you are missing how stack works. You should read the stack user guide, but let me explain briefly. stack uses two files to work:
stack.yaml: It defines from where stack should download packages. By default Stackage. Optionally, git repos, hackage or local libraries.
package.yaml: It defines which libraries you'll be using along with how to build your executable. Dependencies, compiler flags, test, etc...
In general the only thing you need to touch from stack.yaml is the resolver, and then use package.yaml to list your dependencies. So, How does stack.yaml is used?
You should have a line like this
resolver:
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/6.yaml
This specifies the set of packages you gonna use, called: resolver or snapshot. All libraries version within an snapshot are guaranteed to build togheter with no dependency hell. In the example above the resolver is set to lts-18.6. So, If you visit stackage page for that snapshot you'll see all suported libraries and the compiler version: ghc-8.10.4
So let say I want to add QuickCheck to my dependencies. In my package.yaml I would list it down the library dependencies label
library:
dependencies:
- QuickCheck
The version of QuickCheck is determine by the selected resolver (18.6) which in this case is QuickCheck-2.14.2 as you can check in the stackage web. Of course, it is a good practise to specify the actual version in package.yaml
library:
dependencies:
- QuickCheck-2.14.2
But it is not necessary, since the resolver already sets the version from you. If you need another version of the package, then you have to add it to extra-deps, indicating stack that you want packages from lts-18.6 and a different package listed in extra-deps
The stack documentation is fairly good, so you should read it more carefully.

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

Stack won't resolve a 'hidden' dependency

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.

How to get Stack to rewrite my Setup.hs file, after changing to Custom build type?

My project has local external dependencies.
So, I've changed the build-type field, in my *.cabal file, to "Custom" and added these sections to my stack.yaml file:
- location: ../loc_deps
subdirs:
- loc_dep1
- loc_dep2
extra-dep: true
explicit-setup-deps:
"*": true # change the default
But, I can't figure out how to get Stack to rewrite my Setup.hs file, to track these local external dependencies.
In response to the first comment, below:
Is this a sufficient Setup.hs for a Custom build-type?:
import Distribution.Simple
main = defaultMain
I'm expecting that if I touch ../loc_deps/loc_dep1/NeededModule.hs and then run a "stack build", I'll see NeededModule.hs get recompiled, but I'm not seeing that.
In response to #mgsloan (first comment below):
Wrt/ this:
Dependencies do not go in your custom Setup.hs
So, then, is this verbiage, taken from the stack.yaml fields descriptions page, out of date?:
Decide whether a custom Setup.hs script should be run with an explicit
list of dependencies, based on the dependencies of the package itself.
It associates the name of a local package with a boolean. When it's
true, the Setup.hs script is built with an explicit list of packages.

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).

Resources