Skip to content

active-repositories: Don't override fully-deprecated packages#11760

Merged
mergify[bot] merged 1 commit into
haskell:masterfrom
erikd:erikd/dont-override-if-all-deprecated
May 23, 2026
Merged

active-repositories: Don't override fully-deprecated packages#11760
mergify[bot] merged 1 commit into
haskell:masterfrom
erikd:erikd/dont-override-if-all-deprecated

Conversation

@erikd
Copy link
Copy Markdown
Member

@erikd erikd commented Apr 21, 2026

This PR takes over #8997 from the original author Alexander Esgen who unfortunately passed away late last year.

The PR includes tests and additions to the documentation.

When active-repositories includes a repo with :override, and that repo's preferred-versions marks all its versions of a package as deprecated, the index-combining step previously still applied full override semantics, hiding all versions of that package from earlier repos.

Fix by consulting preferred-versions when combining indexes: if lookupDependency finds no preferred version for a package in the override repo, fall back to merge semantics so earlier-repo versions remain visible.

Two changes:

  • PackageIndex: add overrideOrMerge, a per-package Override/Merge strategy
  • IndexUtils: add deprecationAwareStrategy, wired into getSourcePackagesAtIndexState

Fixes #8502

This code was originally authored by Alexander Esgen and sumbitted in a PR over 2 years ago. Erik manually rebased that code onto master and used Claude to add tests and do some very minor refactoring to Alexander's code to make it more testable.

Please read Github PR Conventions and then fill in one of these two templates.


Include the following checklist in your PR:

@erikd erikd force-pushed the erikd/dont-override-if-all-deprecated branch 3 times, most recently from 38c15e5 to c257e5a Compare April 21, 2026 05:28
@erikd erikd force-pushed the erikd/dont-override-if-all-deprecated branch from c257e5a to b5a6079 Compare April 21, 2026 06:04
@erikd
Copy link
Copy Markdown
Member Author

erikd commented Apr 21, 2026

Tagging @andreabedini because he had some comments on Alexanders original PR.

@Mikolaj In July last year you asked if Alexander's PR could be moved forward. As I stated at the top, I have taken this over after Alexander passed.

@Mikolaj
Copy link
Copy Markdown
Member

Mikolaj commented Apr 21, 2026

@Mikolaj In July last year you asked if Alexander's PR could be moved forward. As I stated at the top, I have taken this over after Alexander passed.

Oh, I didn't now about Alexander. I'm honoured to help carry onward his work. Let me also mark @geekosaur, who reviewed the original PR. @erikd, please don't forget to set the needs-review label as soon as you'd like to widen the pool of reviewers.

@Mikolaj
Copy link
Copy Markdown
Member

Mikolaj commented Apr 21, 2026

An initial technical question: does the test have the property that it fails without the PR and succeeds with it? I assume the tests from #11684 don't have this property and so they just check this PR doesn't break how active-repositories should work, right?

@erikd
Copy link
Copy Markdown
Member Author

erikd commented Apr 22, 2026

@Mikolaj If I back out some of the changes in cabal-install/src/Distribution/Client/IndexUtils.hs then 3 out of the 610 tests (running cabal test cabal-install:unit-tests) fail. They all passed before I backed out the changes.

Otherwise, yes, the tests in #11684 were just to test the "active-repositories" features so that these changes did not break that functionality.

@Mikolaj
Copy link
Copy Markdown
Member

Mikolaj commented Apr 22, 2026

Good to know. Are the failing tests the newly added overrideOrMergeTests and/or deprecationAwareStrategyTests?

@erikd erikd force-pushed the erikd/dont-override-if-all-deprecated branch from b5a6079 to 02f4672 Compare April 23, 2026 03:05
@erikd
Copy link
Copy Markdown
Member Author

erikd commented Apr 23, 2026

Inspecting the failures more closely, they are a) intermittent and b) not related to the changes in this PR. For some reason a couple of tests in the UnitTests.Distribution.Client.UserConfig section fail intermittently with things like:

  UnitTests.Distribution.Client.UserConfig
    nullDiffOnCreate:                                                                        OK (0.02s)
    canDetectDifference:                                                                      FAIL
      Exception: /home/erikd/Git/Haskell/cabal/cabal-install/tests/fixtures/project-root/
         test-user-config.tmp: withFile: resource busy (file is locked)
      
      HasCallStack backtrace:
        ioException, called at libraries/ghc-internal/src/GHC/Internal/IO/FD.hs:331:17 in
          ghc-internal:GHC.Internal.IO.FD
      
      Use -p '/canDetectDifference/' to rerun this test only.

I did some further refactoring to expose addIndex so I could add unit tests specifically testing the Merge/Orverride/Skip logic.

There are still separate tests for addIndex and addStategy. Having separate (and cheap execution wise) tests is still worthwhile even though addIndex with an empty [Dependency] list behaves identically to applyStrategy for all three strategies.

Rebased against master as well.

@erikd erikd force-pushed the erikd/dont-override-if-all-deprecated branch from 02f4672 to 71dde16 Compare April 23, 2026 09:31
@philderbeast
Copy link
Copy Markdown
Collaborator

Inspecting the failures more closely, they are a) intermittent and b) not related to the changes in this PR.

Yes, they're not related. These failures are reported in #11686 with a fix in flight with #11759.

@erikd erikd force-pushed the erikd/dont-override-if-all-deprecated branch 3 times, most recently from 689e85c to 2924f25 Compare April 30, 2026 05:23
@erikd erikd force-pushed the erikd/dont-override-if-all-deprecated branch 2 times, most recently from 14f76fa to 2379e8c Compare May 7, 2026 06:16
@erikd
Copy link
Copy Markdown
Member Author

erikd commented May 7, 2026

The CI Bootstrap failure has nothing to do with my PR. The failure is in Python code and my PR does not touch any Python code.

@Mikolaj
Copy link
Copy Markdown
Member

Mikolaj commented May 7, 2026

The CI Bootstrap failure has nothing to do with my PR. The failure is in Python code and my PR does not touch any Python code.

Right, just a transient network failure. Feel free to restart the failed jobs. Let me know if you can't.

@erikd
Copy link
Copy Markdown
Member Author

erikd commented May 8, 2026

Right, just a transient network failure. Feel free to restart the failed jobs. Let me know if you can't.

Pretty sure I already tried restarting it and it failed second time just like the first.

Restarted again 🤞 .

@Mikolaj
Copy link
Copy Markdown
Member

Mikolaj commented May 8, 2026

You are right, the network failure wasn't transient at all. But I've restarted once more and it's gone, finally. :)

@erikd erikd force-pushed the erikd/dont-override-if-all-deprecated branch 3 times, most recently from 5268e09 to a41c69f Compare May 12, 2026 03:12
@Mikolaj Mikolaj requested a review from sebright May 14, 2026 17:29
@erikd erikd force-pushed the erikd/dont-override-if-all-deprecated branch from a41c69f to 8117942 Compare May 15, 2026 05:49
@erikd erikd force-pushed the erikd/dont-override-if-all-deprecated branch 4 times, most recently from 7f044d4 to a621875 Compare May 17, 2026 23:19
Copy link
Copy Markdown
Collaborator

@angerman angerman left a comment

Choose a reason for hiding this comment

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

🫰

@Mikolaj
Copy link
Copy Markdown
Member

Mikolaj commented May 20, 2026

@sebright: does it look to you like this impacts the solver, which would necessitate analyzing the consequences, or is it unrelated, in which case we could probably land it right now?

@sebright
Copy link
Copy Markdown
Collaborator

@Mikolaj I didn't get a chance to review this PR, but it sounds like it only affects the contents of the source package index that is passed to the solver. The solver should be able to handle any set of available packages and versions, so I don't think that this would have much effect on the rest of dependency solving. I'm also guessing that the removal of preferred versions from Hackage (haskell/hackage-server#1498) simplifies this change.

@erikd erikd force-pushed the erikd/dont-override-if-all-deprecated branch from a621875 to 5f04334 Compare May 22, 2026 06:17
@erikd
Copy link
Copy Markdown
Member Author

erikd commented May 22, 2026

@sebright Since you were requested as a reviewer, in order for this to be merged, you either need to review this or remove yourself as a reviewer. Thanks!

@sebright
Copy link
Copy Markdown
Collaborator

@erikd Is the review request blocking Mergify? I had thought that PRs only needed two approvals, without requested changes.

@Mikolaj Mikolaj removed the request for review from sebright May 22, 2026 08:46
@Mikolaj
Copy link
Copy Markdown
Member

Mikolaj commented May 22, 2026

I'm satisfied by the non-review. :) Thank you @sebright!

When active-repositories includes a repo with :override, and that repo's
preferred-versions marks all its versions of a package as deprecated, the
index-combining step previously still applied full override semantics,
hiding all versions of that package from earlier repos.

Fix by consulting preferred-versions when combining indexes: if
lookupDependency finds no preferred version for a package in the override
repo, fall back to merge semantics so earlier-repo versions remain visible.

 Two changes:
  - PackageIndex: add overrideOrMerge, a per-package Override/Merge strategy
  - IndexUtils: add deprecationAwareStrategy, wired into getSourcePackagesAtIndexState

Fixes haskell#8502

This code was originally authored by Alexander Esgen and sumbitted in a
PR over 2 years ago. Erik manually rebased that code onto master and used
Claude to add tests and do some very minor refactoring to Alexander's
code to make it more testable.

Co-Authored-By: Erik de Castro Lopo <erikd@mega-nerd.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@erikd erikd force-pushed the erikd/dont-override-if-all-deprecated branch from 5f04334 to 3a31161 Compare May 22, 2026 23:02
@erikd
Copy link
Copy Markdown
Member Author

erikd commented May 23, 2026

@Mergifyio queue

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 23, 2026

Merge Queue Status

  • Entered queue2026-05-23 01:22 UTC · Rule: default
  • Checks skipped · PR is already up-to-date
  • Merged2026-05-23 01:33 UTC · at 3a31161dacd0bf7d47b00eb0068c1f633cff7ff4 · merge

This pull request spent 11 minutes 20 seconds in the queue, including 3 seconds running CI.

Required conditions to merge
  • #approved-reviews-by >= 2 [🛡 GitHub branch protection]
  • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
  • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
  • any of [🛡 GitHub branch protection]:
    • check-success = Doctest Cabal
    • check-neutral = Doctest Cabal
    • check-skipped = Doctest Cabal
  • any of [🛡 GitHub branch protection]:
    • check-success = Meta checks
    • check-neutral = Meta checks
    • check-skipped = Meta checks
  • any of [🛡 GitHub branch protection]:
    • check-success = docs/readthedocs.org:cabal
    • check-neutral = docs/readthedocs.org:cabal
    • check-skipped = docs/readthedocs.org:cabal
  • any of [🛡 GitHub branch protection]:
    • check-success = Validate post job
    • check-neutral = Validate post job
    • check-skipped = Validate post job
  • any of [🛡 GitHub branch protection]:
    • check-success = fourmolu
    • check-neutral = fourmolu
    • check-skipped = fourmolu
  • any of [🛡 GitHub branch protection]:
    • check-success = hlint
    • check-neutral = hlint
    • check-skipped = hlint
  • any of [🛡 GitHub branch protection]:
    • check-success = Bootstrap post job
    • check-neutral = Bootstrap post job
    • check-skipped = Bootstrap post job
  • any of [🛡 GitHub branch protection]:
    • check-success = whitespace
    • check-neutral = whitespace
    • check-skipped = whitespace
  • any of [🛡 GitHub branch protection]:
    • check-success = Check sdist post job
    • check-neutral = Check sdist post job
    • check-skipped = Check sdist post job
  • any of [🛡 GitHub branch protection]:
    • check-success = Changelogs
    • check-neutral = Changelogs
    • check-skipped = Changelogs

@mergify mergify Bot added the queued label May 23, 2026
@mergify mergify Bot merged commit 6989d21 into haskell:master May 23, 2026
100 of 102 checks passed
@mergify mergify Bot removed the queued label May 23, 2026
@Mikolaj
Copy link
Copy Markdown
Member

Mikolaj commented May 23, 2026

@erikd: BTW, we normally merge by setting a label to give people some more time to react (but in this case there was ample time, so no problem). Please see CONTRIBUTING.md.

@erikd erikd deleted the erikd/dont-override-if-all-deprecated branch May 24, 2026 23:31
@coot
Copy link
Copy Markdown
Collaborator

coot commented May 27, 2026

Have we bumped the cabal-version? This will allow one to require in a *.cabal file that only cabal that supports this change can be used to build a package - a handy feature to make an ecosystem safe.

@ulysses4ever
Copy link
Copy Markdown
Collaborator

This is not a part of the cabal format, and I don't think we want a precedent of bumping the format for unrelated changes in the tool.

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.

Name security in additional package repositories

9 participants