Do I have to repeat all dependencies in the test configuration? - haskell

This bugs me time and again, basically if I create a test-suite in the cabal configuration I add the projects src folder to the test suites hs-source-dirs section and repeat all dependencies in build-depends. A typical project might look like:
-- in file "foo.cabal"
library
build-depends: a, b, c
exposed-modules: Foo, Bar
hs-source-dirs: src
test-suite tests
build-depends: foo, a, b, c
hs-source-dirs: test
The other option is to include src in the test suites hs-source-dirs as well.
Both of them require me to specify all build dependencies in the test case, as far as I know. Is there a way around this?

It should work as is but there is a reported bug when you use it with cabal repl
Overall it seems work with cabal test but if you try to load the test-file into cabal repl you might get an error like this:
Could not find module ‘XYZ’
It is a member of the hidden package ‘XZY-[ver]’.
Perhaps you need to add ‘XYZ’ to the build-depends in your .cabal file.
Use -v to see a list of the files searched for.
So right now it might be a good idea to indeed copy the dependencies but hopefully this will get resolved shortly

Related

Entry point for test suite with multiple files in Cabal project?

New to Cabal, so sorry if this is obvious, but I obviously want to have more than one file in my Cabal project's test suite, yet the .cabal file is insisting on being given an entrypoint. What do I put for this?
For example, if I have two modules in my library and want to test each in their own test file. One is no more important than the other, so how do I go about making one of the files an entrypoint?
You could make two test suites.
test-suite A
main-is: test-module-A.hs
test-suite B
main-is: test-module-B.hs
Or you could make a single suite that imports both test modules.
test-suite both
main-is: test-both.hs
other-modules: TestA, TestB

Exposing internal modules to tests in Cabal

I'm contributing to an open source project which defines its project setup in a cabal file that looks like this (omitting lots of properties that are not relevant for this problem):
library
hs-source-dirs: src
build-depends:
base >= 4.9 && < 5,
some-other-deps
exposed-modules:
Data.Foo.Bar,
Data.Foo.Baz
other-modules:
Data.Foo.Bar.Internal
test-suite test
hs-source-dirs:
tests
build-depends:
foo-library
other-modules:
Foo.Bar.Tests,
Foo.Baz.Tests
Now, in order to test the feature I'm adding, I want the tests to have access to the Data.Foo.Bar.Internal module, but since it's hidden in the library, I can't access it from the tests.
I looked at the cabal docs which suggested adding a third component - an internal library (unfortunately not linkable, but search for "internal libraries"). If I understand the documentation correctly, I should be able to do something like this:
library foo-internal
hs-source-dirs: src
build-depends:
base,
some-other-deps
exposed-modules:
Data.Foo.Bar.Internal
library
hs-source-dirs: src
build-depends:
base >= 4.9 && < 5,
foo-internal,
some-other-deps
exposed-modules:
Data.Foo.Bar,
Data.Foo.Baz
test-suite test
hs-source-dirs:
tests
build-depends:
foo-library,
foo-internal
other-modules:
Foo.Bar.Tests,
Foo.Baz.Tests
but running stack build here gives me warnings that Data.Foo.Bar.Internal "should be added to exposed-modules or other-modules in ./foo.cabal", and then a build error in the test that seems to be caused by failed unification (it points to a function argument for a function defined in the library, says that its type must be Data.Foo.Bar.Internal.Qux defined in package foo, and that the type foo:Data.Foo.Bar.Internal.Qux don't match).
How can I expose internal modules to the test suite, without exposing them also to consumers of the library?
As mentioned in the comments, different components (internal libraries, executables) should have modules under different roots.
This is a recurrent point of confusion. For another example: https://stackoverflow.com/a/6711739/6863749
There is an open ticket on Cabal's issue tracker about clarifying this with a suitable warning; it's apparently non-trivial to detect this situation reliably because it overlaps with legitimate use cases: https://github.com/haskell/cabal/issues/5335

cabal doesn't find Source.hs

My project structure is as follows:
~/.../project_name
project_name.cabal
Setup.hs
src/
Main.hs
Data/
...
test/
MainTestSuite
...
I have (amongst others) the following lines in my project.cabal:
build-type: Simple
...
executable project_name
main-is: Main.hs
...
hs-source-dirs: src
When I cabal configure (works fine) and then cabal build I get the error message:
cabal: can't find source for Setup in src, dist/build/autogen
It works when I put Source.hs in src but this seems messy to me and I haven't seen this in other projects, where Source.hs is always in the project root. How do I get cabal to find Source.hs?
As an aside: What's the purpose of Source.hs anyways?
The problem was caused by accidently adding the Source file as a dependency in other-modules in the cabal-file of the project ... that caused all the trouble.
hs-source-dirs: ., src comes to mind as a fast fix.
That's what my projects use, and I generate my cabal files automatically (so I suppose that's the default).

Install part of program with cabal like library

I have simple program written with haskell, i build it with cabal. For example i my program has next directory structure:
my-prog
* Main.hs
* my-prog.cabal
* SomeDirWithHsFiles
- File1.hs
- File2.hs
I want that when i'll make cabal build and cabal install (maybe something else), SomeDirWithHsFiles with *.hs files, installed like a normal haskell library, and then i'll use File1.hs and File2.hs modules in other programm.
How can i do this?
Thank you.
You need to declare your additional files in a library section, like so:
library
exposed-modules: File1
File2
executable foo
main-is: Main.hs
See for example, xmonad's .cabal file.

Why does "cabal sdist" not include all "files needed to build"?

According to the wiki entry,
It packages up the files needed to build the project
I have a simple executables-only .cabal project, which basically contains
Executable myprog
hs-source-dirs: src
main-is: MyMain.hs
and is made up of some additional .hs files below src/ beyond src/MyMain.hs. E.g., src/Utils.hs and a few others.
cabal build has no problems building myprog, and compiles the required additional .hs files below src/, but cabal sdist does not, thus creating a dysfunctional source-tarball. What am I doing wrong? How do I tell cabal to include all source files below hs-source-dirs?
As a side-note, with GNU Autotools, there was a make distcheck target, which would first build a source-tarball, and then try to build the project via the newly generated source-tarball, thus ensuring everything's ok. Is there something similar for cabal, in order to make sure my source-tarball is sound?
You should list the other Haskell files in the .cabal file, inside the Executable stanza.
other-modules: Utils AFewOthers
The distribution only includes source files that are listed in your .cabal file. Cabal has no other way to detect which source files are in your package. You could still build because cabal build calls ghc --make, and ghc will find and compile all the source files it needs.

Resources