Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix qualifiers in cabal freeze #9811

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

alt-romes
Copy link
Collaborator

@alt-romes alt-romes commented Mar 15, 2024

Qualifiers in the cabal freeze should definitely not always be "any".

(it can cause inconsistencies, such as
    `cabal freeze --constraint=... && cabal build`
being different from
    `cabal build --constraint=...`
)

In this commit we propagate information on the scopes in which each
package was solved to be able to generate a proper freeze file where
each package solved is constrained in the scope it was solved in.

Fixes #9799


Template Α: This PR modifies cabal behaviour

Include the following checklist in your PR:

  • Patches conform to the coding conventions.
  • Any changes that could be relevant to users have been recorded in the changelog.
  • The documentation has been updated, if necessary.
  • Manual QA notes have been included.
  • Tests have been added. (Ask for help if you don’t know how to write them! Ask for an exemption if tests are too complex for too little coverage!)

Add tests for haskell#9799 about freeze qualifying all packages with 'any'
constraint scope.
@alt-romes alt-romes self-assigned this Mar 15, 2024
@alt-romes alt-romes force-pushed the wip/romes/9799-3 branch 2 times, most recently from ac13f9a to ac435fd Compare March 15, 2024 12:22
Qualifiers in the cabal freeze should definitely not always be "any".

(it can cause inconsistencies, such as
    `cabal freeze --constraint=... && cabal build`
being different from
    `cabal build --constraint=...`
)

In this commit we propagate information on the scopes in which each
package was solved to be able to generate a proper freeze file where
each package solved is constrained in the scope it was solved in.

Fixes haskell#9799
in the graph, the packages would already be distinct because if two different versions were picked they would get two different unit ids. this change makes it possible to have two different nodes in the map with the same unit-id (e.g. solver linked the setup and top-level package instances). this is not good
This reverts commit 4953db1.
@alt-romes alt-romes marked this pull request as draft April 3, 2024 11:06
Copy link
Collaborator Author

@alt-romes alt-romes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Despite these comments, I recall trying this and realizing it was not a good idea.

Here was the attempt at using (UnitId, ConstraintScope) as Key and extending SolverId with the scope: 4953db1

The comment I wrote at the time saying that this is wrong is:

In the graph, the packages would already be distinct because if two different versions were picked they would get two different unit ids. This change makes it possible to have two different nodes in the map with the same unit-id (e.g. solver linked the setup and top-level package instances). This is not good.

Why is this not good? I don't recall.

Comment on lines +28 to +30
-- The constraint scope field refers to the scope in which this package was resolved.
data ResolverPackage loc = PreExisting InstSolverPackage ConstraintScope
| Configured (SolverPackage loc) ConstraintScope
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The packages that are part of the plan now also store information about the scope they were resolved in. This information is propagated down to cabal-install (see GenericInstallPlan).

Comment on lines 181 to +184
data GenericPlanPackage ipkg srcpkg
= PreExisting ipkg
| Configured srcpkg
| Installed srcpkg
= PreExisting ipkg ConstraintScope
| Configured srcpkg ConstraintScope
| Installed srcpkg ConstraintScope
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In cabal-install our understanding of the install plan must also consider, for every package in the plan, the scope it was solved in.

Comment on lines 53 to +55
type Key (ResolverPackage loc) = SolverId
nodeKey (PreExisting ipkg) = PreExistingId (packageId ipkg) (installedUnitId ipkg)
nodeKey (Configured spkg) = PlannedId (packageId spkg)
nodeKey (PreExisting ipkg _) = PreExistingId (packageId ipkg) (installedUnitId ipkg)
nodeKey (Configured spkg _) = PlannedId (packageId spkg)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that when we construct a graph of resolver packages in the solver the keys don't have this information (even though the nodes do); thus same packages resolved in different constraint scopes will be collapsed and only one copy will survive.

In cabal-install, when we construct a GenericInstallPlan from the graph of resolver packages we have only kept one of each package, even if originally many could have existed in different scopes.

Comment on lines 216 to +219
type Key (GenericPlanPackage ipkg srcpkg) = UnitId
nodeKey (PreExisting ipkg) = nodeKey ipkg
nodeKey (Configured spkg) = nodeKey spkg
nodeKey (Installed spkg) = nodeKey spkg
nodeNeighbors (PreExisting ipkg) = nodeNeighbors ipkg
nodeNeighbors (Configured spkg) = nodeNeighbors spkg
nodeNeighbors (Installed spkg) = nodeNeighbors spkg
nodeKey (PreExisting ipkg _) = nodeKey ipkg
nodeKey (Configured spkg _) = nodeKey spkg
nodeKey (Installed spkg _) = nodeKey spkg
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here we lose this information as well..., a UnitId refers only to a package, not the Scope in which we use this UnitId

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cabal freeze qualifies all package constraints with any
2 participants