opam
opam copied to clipboard
Multiple switches in PATH after logout
How to have multiple opam switches in your PATH at the same time
- (may be optionnal, I can't really test this) Use fish as your shell
- Answer yes to the first question of
opam init(so you havesource ~/.opam/opam-init/init.fishin.config/fish/config.fish). The second question (about the env-hook) doesn't seem to matter. - Have multiple global switches (local switches seem to behave normally). Let's name them foo, bar & baz.
- Have foo be the active switch. You should have
~/.opam/foo/binin your PATH at this point. - Log out.
- Log back in.
- Run
opam switch bar. You obviously should have~/.opam/bar/binin your PATH, but you'll also see~/.opam/foo/bin. Note that in my scenario they are not side by side, but in different part of the PATH (the 'correct' one being leftmost, with the other one in the middle). YMMV. - Repeat steps 4-6 with
bar, thenbaz... - Congratulations, you now have multiple switches in your PATH! Enjoy the ensuing chaos!
- Reboot the whole computer to solve this, until the next login of course.
what version of opam do you have?
2.1.5, it's a fresh install with the script on opam (https://opam.ocaml.org/doc/Install.html#Binary-distribution). Note that the problem was already there with my system install (apt install opam), and that had version 2.1.2
Could you try using the latest 2.2.0~alpha3 release just in case? (don’t worry it’s very stable, the only reason it’s an alpha verison is that the Windows support is not completed)
bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh) --dev"
Just did that, and it doesn't solve it, sorry.
Can you share the OPAM* variables status before calling init scripts? You can have that by adding something like env | grep OPAM in you config.fish before init.fish sourcing.
Could you also try to replace isatty by interactive in ~/.opam/opam-init/init.fish and reboot to see if that helps?
related to https://github.com/ocaml/opam/issues/4649
Can you share the OPAM* variables status before calling init scripts? You can have that by adding something like
env | grep OPAMin youconfig.fishbeforeinit.fishsourcing.
With this in my config.fish:
# opam debugging
set debug_file_name "$HOME/opam_debug.txt"
echo "$(date)" >>$debug_file_name
env | rg opam >>$debug_file_name
After a reboot, I get this: Note that 'standard' is the name of the global switch that was active before the reboot
mer. 20 déc. 2023 10:42:59 CET # This was from the login shell, which isn't interactive
mer. 20 déc. 2023 10:43:03 CET # Shell manually started:
PATH=<a whole lot of personal stuff>:~/.local/bin:~/.cargo/bin:~/.opam/standard/bin:/usr/local/sbin:<more personal stuff>
OPAM_SWITCH_PREFIX=~/.opam/standard
OCAML_TOPLEVEL_PATH=~/.opam/standard/lib/toplevel
CAML_LD_LIBRARY_PATH=~/.opam/standard/lib/stublibs:~/.opam/standard/lib/ocaml/stublibs:~/.opam/standard/lib/ocaml
# Changed 'isatty' to 'status 'is-interactive' in ~/.opam/opam-init/init.fish
# and rebooted
mer. 20 déc. 2023 10:56:13 CET # login again
mer. 20 déc. 2023 10:57:02 CET # manual shell again
[exact same thing as the big one above]
# Here I did 'opam switch fmt', and logged out (not a reboot) and logged back in
mer. 20 déc. 2023 10:58:23 CET
[exact same thing as the big one again]
mer. 20 déc. 2023 10:58:33 CET # Two opam switches! vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
PATH=<a whole lot of personal stuff>:~/.local/bin:~/.cargo/bin:~/.opam/fmt/bin:~/.opam/standard/bin:/usr/local/sbin:<more personal stuff>
OPAM_SWITCH_PREFIX=~/.opam/fmt
OCAML_TOPLEVEL_PATH=~/.opam/fmt/lib/toplevel
CAML_LD_LIBRARY_PATH=~/.opam/fmt/lib/stublibs:~/.opam/fmt/lib/ocaml/stublibs:~/.opam/fmt/lib/ocaml
# Here I did 'opam switch coq', and logged out/in again
mer. 20 déc. 2023 11:37:20 CET
# Same thing as right above, but interestingly it's not in the same order???
CAML_LD_LIBRARY_PATH=~/.opam/fmt/lib/stublibs:~/.opam/fmt/lib/ocaml/stublibs:~/.opam/fmt/lib/ocaml
OCAML_TOPLEVEL_PATH=~/.opam/fmt/lib/toplevel
OPAM_SWITCH_PREFIX=~/.opam/fmt
PATH=<a whole lot of personal stuff>:~/.local/bin:~/.cargo/bin:~/.opam/fmt/bin:~/.opam/standard/bin:/usr/local/sbin:<more personal stuff>
mer. 20 déc. 2023 11:37:25 CET # Three opam switches!
PATH=<a whole lot of personal stuff>:~/.local/bin:~/.cargo/bin:~/.opam/coq/bin:~/.opam/fmt/bin:~/.opam/standard/bin:/usr/local/sbin:<more personal stuff>
OPAM_SWITCH_PREFIX=~/.opam/coq
OCAML_TOPLEVEL_PATH=~/.opam/coq/lib/toplevel
CAML_LD_LIBRARY_PATH=~/.opam/coq/lib/stublibs:~/.opam/coq/lib/ocaml/stublibs:~/.opam/coq/lib/ocaml
Adding more context as I dive deeper into this:
in my config.fish I have the following before sourcing init.fish (maybe a bit overkill at this point)
# opam debugging
set debug_file_name "$HOME/dumpfile"
echo >>$debug_file_name
if status is-login
echo "This is a login shell" >>$debug_file_name
else if status is-interactive
echo "This is an interactive shell" >>$debug_file_name
else
echo "This is neither an interactive nor a login shell" >>$debug_file_name
end
env | rg opam >>$debug_file_name
At the time of last startup/login, my global switch was coq. I then ran opam switch fmt, and closed the shell (not a full logout of my gnome session, just ctrl-D). I then start a new terminal, and find at the end of the dumpfile:
This is a login shell
[nothing here]
This is an interactive shell
PATH=[personal stuff, abbreviated as A]:~/.opam/coq/bin:[more stuff abbreviated as B]
OPAM_SWITCH_PREFIX:~/.opam/coq
[OCAML_TOPLEVEL_PATH & CAML_LD_LIBRARY_PATH omitted as they're unsurprising and redundant]
In my new terminal:
> opam switch show
fmt
> echo $PATH
~/.opam/fmt/bin [A] ~/.opam/coq/bin [B]
> opam env
[...]
set -gx PATH ~/.opam/fmt/bin [A] ~/.opam/coq/bin [B]
So I assume something has gone wrong before the interactive shells started (otherwise we'd have fmt right at the start, after the login notice), and try this (still in the same terminal)
echo "hello" | fish 2>/dev/null
## in dumpfile
This is neither an interactive nor a login shell
PATH=[A]:~/.opam/fmt/bin:~/.opam/coq/bin:[B]
OPAM_SWITCH_PREFIX=~/.opam/fmt
MANPATH=~/.opam/fmt/man #Oh that's new!
> echo "env | rg opam" | fish >other_file
## in dumpfile (NOT other_file)
[exact same thing as above, with the same hash in OPAM_LAST_ENV]
## in other_file
PATH=~/.opam/fmt/bin:[A]:~/.opam/fmt/bin:~/.opam/coq/bin:[B] # Oh a triple!
OPAM_SWITCH_PREFIX=~/.opam/fmt
MANPATH=~/.opam/fmt/man:~/.opam/fmt/man #???????
Any ideas about where this could come from?
This is a login shell [nothing here]
This is an interactive shell PATH=[personal stuff, abbreviated as A]:~/.opam/coq/bin:[more stuff abbreviated as B]
To me the most surprising bit is here. From what I remember from your config.fish the opam specific bit is at the end, however stuff that you do before (all the stuff abbreviated as A) appears prepended which makes no sense to me if it's done before. Does fish do things in a delayed manner when you use fish_add_path or stuff like that? Maybe there is something else that acts afterwards (e.g. something in $HOME/.config/fish/conf.d maybe?)
Also, from a quick experiment, i can see that opam modifies the PATH to always put it at the top. Maybe there is something else trying to do the same?
Was this fixed by #5866 ?
Indeed!