haskell / haskell/cabal

Unexpected project file semantics with conditionals

Open
#11,525 3 comments 0 reactions 0 assignees View on GitHub
re: project-file type: bug
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

Description

Project file semantics seem to be confusing/broken with conditionals.

This is especially problematic in light of project file imports where we can very well have some repetition and want things that come later as overrides.

# Reproducer

I've created a reproducer where the test fails to compile, but I'm disabling the tests in a convoluted way in the cabal project file.

These are all run on a linux system.

## With conditional

`cabal.project`:

```cabal
packages: ./cabal-project-repro.cabal

if !os(windows)
package *
Tests: True

package *
Tests: False
```

Running `cabal build` results in:

```
test/Main.hs:4:8: error: [GHC-88464]
Variable not in scope: puStrLn :: String -> IO ()
Suggested fix: Perhaps use ‘putStrLn’ (imported from Prelude)
|
4 | main = puStrLn "Test suite not yet implemented."
| ^^^^^^^
[2 of 2] Linking dist-newstyle/build/x86_64-linux/ghc-9.8.4/cabal-project-repro-0.1.0.0/x/filemonitor-test/build/filemonitor-test/filemonitor-test
Error: [Cabal-7125]
Failed to build test:cabal-project-repro-test from cabal-project-repro-0.1.0.0.
```

So the tests are actually built!

Reproducer: `git clone https://github.com/hasufell/cabal-project-repro.git --branch conditional`

## Without conditional

Just removing the os-conditional suddenly makes it succeed.

`cabal.project`:

```cabal
packages: ./cabal-project-repro.cabal

package *
Tests: True

package *
Tests: False
```

Reproducer: `git clone https://github.com/hasufell/cabal-project-repro.git --branch no-conditional`

## Explanation attempt

My guess is that the conditionals are resolved later and so actually come **last** when all the expressions are applied and resolved to packages. I don't think that's something a reader would expect to happen, just looking at the ordering of expressions in the file.

Contributor guide

Open the contributing guide

Research direction

Start with the conditional and non-conditional cabal.project files in the linked reproducer branches, then run cabal build on Linux to compare their behavior. Trace how the package and Tests settings are ordered and resolved; done means the conditional configuration follows the documented or expected override semantics and the reproducer builds accordingly.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
build-system
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.