-
Notifications
You must be signed in to change notification settings - Fork 358
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
Completely refactor the way orphan packages are handled (and add tests) #4969
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks fine, the tests are clear and show that it works. LGTM
ae22bc8
to
847b78f
Compare
847b78f
to
4ba7831
Compare
Note: this is now based on top of #4973, which includes most of the tests, and should be rebased once that is merged. |
2 opam-rt tests are failing:
|
4ba7831
to
e1eb9d4
Compare
Ok, now all should be ok:
|
e1eb9d4
to
ac42c99
Compare
Ok, only remaining failures should be fixed by the PR on opam-rt; apparently the trick that used the same-named branch of opam-rt for tests is no longer here, so we should probably merge #4973, then ocaml-opam/opam-rt#76, then re-run CI for this PR. |
The plan is to remove the pre-processing as much as possible and let the solver handle them as much as possible. Then some post-processing could be done to remove the irrelevant parts of the solution.
Accounting for the more restrictive handling of orphans, and working around it with `pin --current`.
- fixed removal of orphan packages (the sanitization of the request was too strict) - pass the list of relevant packages explicitely in the request. Previously this was inferred from the wish_install/upgrade/remove fields, assuming no filtering if that was empty, but: * `opam upgrade -a foo` would wrongly restrict to `foo` * the post-action on unpinning had to explicitely be an upgrade or remove, while now we can just let the solver choose and still properly trim the solution.
Can happen when changing the pinned-to version or unpinning. Also includes a small rewrite of avoid-version handling in the package universe. Now 'upgrade' requests are split for the solver: for pinned packages, it's sufficient to file an 'install' request since only one version is expected to be available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM aside from a small request
(** Returns [true] when the package has the [avoid-version] flag and there isn't | ||
already a version with that flag installed (which disables the | ||
constraint) *) | ||
val avoid_version : 'a switch_state -> package -> bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this PR also changes the code for the handling of the avoid-version
flag, i just noticed there wasn’t any tests for this flag. Could you add some if you have some time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved some code around and replaced a Set.fold+exists by a filter for efficiency, but that should be functionnally equivalent; indeed there is no fundamental reason for this to be in this PR, I just stumbled upon it while I was writing the PR.
You're right about tests — though I'd prefer not to stall this and add them in another PR.
Follows from ocaml#4969 and fixes ocaml#4727
Follows from ocaml#4969 and fixes ocaml#4727
Follows from ocaml#4969 and fixes ocaml#4727
Follows from ocaml#4969 and fixes ocaml#4727
Follows from ocaml#4969 and fixes ocaml#4727
Orphan packages are packages which are installed within a switch, but no longer available. Without special handling, they become invisible to the solver, which has quite a few drawbacks:
For these reasons, they need special care. The current approach is complex code in OpamClient that analyses them, their relationships with the user request, and lies about the universe so they can be kept when unrelated, or if they don't matter.
That code was tricky, complex, computing (reverse) dependency cones, intersections thereof and whatnot, costly — requiring a few preliminary conversions of the opam state to a solver universe, and, I found out, still incomplete and incorrect around the edges.
This PR implements a much simpler solution, that supplies the whole universe to the solver with a minimum of lies (orphans are included, but with their unavailability encoded as a fake dependency). Then, there is post-processing on the action graph after the solution is computed for removing sub-graphs that are disjoint from the requested actions, to avoid unrelated actions from being triggered.
The additional tests show a good behaviour in the considered cases (including some where the old system was incorrect).
IMPORTANT: major change compared to the previous behaviour
RELATED THINGS TO CONSIDER:
opam pin --current <pkg>
that pins the package to its current state. Allows manual bypassing of an upstream removed packages, and would also offer a more consistent workaround for skipping pending reinstallsopam upgrade --fixup
has been simplified because it used to consider the specific status of orphan packages. Maybe consider re-implementing it with something likeopam upgrade --criteria=fixup --best-effort --update-invariant
?