ocaml / opam

opam is a source-based package manager. It supports multiple simultaneous compiler installations, flexible package constraints, and a Git-friendly development workflow.
https://opam.ocaml.org
Other
1.24k stars 353 forks source link

Fixes to reversal of environment updates #5935

Closed dra27 closed 4 months ago

dra27 commented 5 months ago

Fixes for #5838, #5925 and #5926. This PR has become quite an epic rabbithole, but the fixes and changes are very, very intertwined. It is possible to separate the final fix for #5926 to a subsequent PR, but the final fix itself is actually quite small.

The first commit adds a new sort operation to the reftest language. While working on this, the stability of the output of opam env and the stability of the output when using unordered made making the true effect of each commit tricky. I'm still not sure that unordered is behaving as well as it should when there's actually a change to the output (i.e. when one line changes, it's allowing some unchanged lines to be re-ordered noisily in the diff).

I then add a whole range of tests:

There have been a lot of issues and PRs in the past to do with the treatment of := and =: principally where MANPATH is concerned. I'm relatively confident that the approach for this before has not been strictly correctly (and is the cause of the issue being seen in #5926). For both PATH (as defined by Posix) and MANPATH (as defined by the tool itself), an unset value, an empty value and the value : are all equivalent. For PATH, that means the current directory and all of these entries are literally equivalent to PATH=.. For MANPATH, those three entries mean "use the default search path".

Now, as far as I can see the previous discussions have been about ensuring that MANPATH has a leading or trailing :, to ensure that opam never hides the default path. Thus, if MANPATH is not set, then we have MANPATH =: "%{man}%" giving us :/home/dra/.opam/default/man. However, the focus should not be on having a leading or trailing :, the focus should be on ensuring that a "blank" entry is created if needed (this is the rule for FOO := "a" and FOO =: "a" are a: or :a respectively if FOO is unset or empty) and but then for all updates separately ensuring that the blank entry is preserved.

i.e. if FOO is :a then both FOO += "b" and FOO := "b" should set FOO to b::a

The actual fixes then proceed as:

TODO

dra27 commented 5 months ago

OK, the fix I was proposing I didn't like because it didn't preserve unnecessarily escaped parts of existing variables. I then further found it regressed #4861 and consequently broke the msvs-detect package.

I have a plan (which I'm currently implementing) - a failing test for the main issue (#5838) added and for the first bit of the fix, which I am certain is right. The change I think is required for #5838 without breaking #4861 I think will also address #5925 and #5926, so I've added tests showing the failure behaviour for them as well.

dra27 commented 5 months ago

The change in c4167f6a7ee8248b7aae0fe65f3695703e80c73b requires environment files to be reset - @rjbou... does that happen naturally with a format upgrade?

That said, it's making me wonder if we should ever be "putting" rewrite_default in the environment cache files anyway?

kit-ty-kate commented 4 months ago

Thanks!