Multiple Cabal components
Currently, multiple Cabal components don’t work. You can work around this with
the Cabal test-dev
trick as described by the venerable Jade
Lovelace. This works by defining a new component in our .cabal
file which
includes the sources from the library and the tests, which has the added
benefit of speeding up compile times by allowing the compilation of different
components to be interleaved.
You can see this demonstrated in the ghciwatch test sources here. We define four components:
library
tests
- An internal
test-lib
library - An internal
test-dev
library
Then, we can use a command like cabal v2-repl test-dev
to run a GHCi session
containing both the library and test sources.
The package.yaml
should look something like this:
---
spec-version: 0.36.0
name: my-simple-package
version: 0.1.0.0
flags:
local-dev:
description: Turn on development settings, like auto-reload templates.
manual: true
default: false
library:
source-dirs: src
tests:
test:
main: Main.hs
source-dirs:
- test-main
ghc-options: -threaded -rtsopts -with-rtsopts=-N
when:
- condition: flag(local-dev)
then:
dependencies:
- test-dev
else:
dependencies:
- my-simple-package
- test-lib
internal-libraries:
test-lib:
source-dirs:
- test
test-dev:
source-dirs:
- test
- src
when:
- condition: flag(local-dev)
then:
buildable: true
else:
buildable: false
Then, we can set the local-dev
flag in our cabal.project.local
, so that we
use the test-dev
target locally:
package my-simple-package
flags: +local-dev
haskell-language-server
Defining the test-dev
component does tend to confuse
haskell-language-server
, as a single file is now in multiple components. Fix
this by writing an hie.yaml
like this:
cradle:
cabal:
component: test-dev