haskell / haskell/cabal

Cabal REPL stack overflows when working around lack of support for multiple home units

Open
#9,240 5 comments 0 reactions 0 assignees View on GitHub
cabal-install: cmd/repl type: bug
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

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 https://github.com/ndmitchell/ghcid/issues/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.

Contributor guide

Open the contributing guide

Research direction

Start with the reproduction repository and its Make rules: run `make watch-test`, then `make watch-server-broken`, and compare the two documented workaround targets. Investigate the `cabal v2-exec` environment, especially `GHC_ENVIRONMENT`, and reproduce the stack overflow before the REPL opens. Done means the reported command-line tool workflow no longer overflows under the described library and test-suite setup.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
build-system, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.