haskell / haskell/cabal

new-freeze doesn't allow for different flag assignments in different instances of a package.

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

Description

new-freeze uses constraints such as `any.my-build-tool-dep ==1.0 || ==2.0` to allow multiple versions of a package, but it doesn't allow those versions to have different flag assignments. I found this issue when I tried to add an `any` qualifier to flag constraints, as in https://github.com/grayjay/cabal/commit/c1f30971b16247a5454f4512f38d90a46439d7f5.

The `projectFreezeConstraints` function in `D.C.CmdFreeze` appears to create flag constraints from a single instance of each package, by calling `Map.fromList`:

https://github.com/haskell/cabal/blob/3b3a8d2b1ba6e3a1fd894fc9bef92d7acfcadc94/cabal-install/Distribution/Client/CmdFreeze.hs#L198-L205

I modified the test [`cabal-testsuite/PackageTests/NewFreeze/new_freeze.test.hs`](https://github.com/haskell/cabal/blob/3b3a8d2b1ba6e3a1fd894fc9bef92d7acfcadc94/cabal-testsuite/PackageTests/NewFreeze/new_freeze.test.hs) by adding a flag to the build tool package, where one version of the build tool could only be built with the flag set to true and the other version could only be built with the flag set to false (https://github.com/grayjay/cabal/commit/de035c97107d7376d15a41cd8a452797c25f8be2). That caused the test to fail when cabal was built with https://github.com/grayjay/cabal/commit/c1f30971b16247a5454f4512f38d90a46439d7f5. (It succeeded with cabal built from master, because the constraint wasn't qualified, and it didn't apply to build tools.) The freeze file only contained one flag constraint, `any.my-build-tool-dep +my-flag`:

```
constraints: any.base ==4.10.0.0,
any.ghc-prim ==0.5.1.0,
any.integer-gmp ==1.0.1.0,
any.my-build-tool-dep ==1.0 || ==2.0,
any.my-build-tool-dep +my-flag,
any.my-library-dep ==1.0,
any.rts ==1.0
```

#3502 would fix this issue, but we could also improve new-freeze constraints without #3502 by filtering out constraints for flags that have conflicting values. For example, cabal could avoid constraining `my-flag` in the example above since the install plan uses both `+my-flag` and `-my-flag`.

Contributor guide

Open the contributing guide

Research direction

Start with projectFreezeConstraints in cabal-install/Distribution/Client/CmdFreeze.hs and the NewFreeze test in cabal-testsuite/PackageTests/NewFreeze/new_freeze.test.hs. Reproduce the differing flag assignments for multiple package instances, then verify the generated freeze constraints preserve those assignments or omit conflicting flag constraints.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.