Description
Describe the bug
Since Cabal lacks multiple home units support, when using Cabal to power the REPL that GHCid sends reload commands to, you can either load the test suite component, watch for changes to the test suite only and not the library and auto-rerun the test suite on build success, or you can load the library component, watch for changes to the library only and not the test-suite and auto-rerun a library entrypoint on build success (like a web server).
I'm sure you could even run two GHCid processes so that one reruns the tests and the other reruns the server, but the server will only reload when the library changes (not a problem) and the tests will only reload when the tests change (a pretty big problem).
The workaround is to add the library hs-source-dir
to the test suite component, as well as the library modules to the test suite's other-modules
, so that GHCid can detect changes to library files as changes to the test suite files as well. Any exposed-modules
library entrypoints that you want GHCid to also be able to run (like a server) on build success, perhaps in a second process, must be in the other-modules
of the test suite.
You can do all this with a common stanza, and I haven't tried without it (way too much duplication otherwise). All good, as the common GHCid refrain goes, right? Wrong!
All good if you run ghcid
directly from the Cabal store (which you can get by doing cabal v2-exec -- which ghcid
or similar), but if you just run ghcid
via cabal v2-exec
, running the GHCid process which watches the library and auto-reruns the server right after running the GHCid process which watches the test suite and auto-reruns the test suite results in a stack overflow before GHCid can even open the REPL it will send commands to.
This then necessitates another workaround on top of the fact that I'm already only doing this to work around Cabal's lack of support for multiple home units.
To Reproduce
Check out my repo https://github.com/habibalamin/ghc-env-breaks-ghcid-server-watch-using-lib-home-and-test-suite-imports-lib-deps-from-common-stanza.
Run make watch-test
, Ctrl-C it, then run make watch-server-broken
.
Expected behavior
I expect Cabal to just be able to load multiple units, and this will even allow me to just do the whole thing in a single GHCid process that watches both library and test code, then on build success, either runs the test suite to completion and the server right afterwards, or just runs them both in parallel somehow (which requires handling interleaving screen output, but that'd be my responsibility, not Cabal's or GHCid's).
Barring that, with the workaround, I expect to be able to just use cabal v2-exec
to run any command line tool that is installed in my build-tool-depends
, like GHCid (although it's more of a dev tool than a build tool, perhaps that can be another ticket), without it causing funky interaction and state issues.
System information
- macOS Ventura 13.5.1 on Apple Silicon M1 Pro
- GHCup 0.1.19.4
- Cabal library 3.10.1.0 via aforementioned GHCup
- Cabal 3.4 package description file
- GHC 9.4.7 via aforementioned GHCup
Additional context
I found two workarounds.
The cabal v2-exec
sets a GHC_ENVIRONMENT
environment variable that seems to cause the breakage, which you can unset with env
before running the Cabal REPL.
The other workaround is to run the Cabal REPL with the test suite component instead of the library component even when running the GHCid process that watches the library and auto-reruns the server instead of the test suite.
In the reproduction repo, see Make rules, watch-server-workaround-use-test-suite-home-unit
and watch-server-workaround-no-ghc-environment
, for the implementations of watch-server
w/ the respective workarounds.
Basic code quality issues with these are outlined in the reproduction repo.
See ndmitchell/ghcid#320 for the GHCid ticket relating to its inability to monitor test-suite AND library changes with Cabal, due to Cabal's lack of support for multiple home units.
Activity