opam
opam copied to clipboard
opam switch create . fails when _opam exists
Just showing @ryangibb how to setup an opam environment from scratch, and we observed that it's quite confusing when opam switch create . fails that it's not idempotent. If an _opam directory exists, then it fails but doesn't give a hint on how to continue. We had to rm -rf _opam (which doesn't seem safe to a beginner) and then opam switch create . again once the underlying issue was fixed.
It would be nice if opam switch create would give a direction on how to recover from the fact that an _opam directory exists already, perhaps with a deletion instruction or a -f to continue regardless.
Can you precise the use case ? opam display a message when a local switch is already existing, and ask to clean up in case of failing initialisation:
$ pwd
/tmp/5073
$ opam switch create --empty .
$ opam switch create --empty .
[ERROR] There already is an installed switch named /tmp/5073
# remove switch from known switches
$ vim ~/.opam/config
$ opam switch create --empty .
[ERROR] There already is an installed switch named /tmp/5073
# failing switch initilisation
$ opam switch remove .
Switch /tmp/5073 and all its packages will be wiped. Are you sure? [Y/n] y
$ opam switch create . ocaml.4.10.0
<><> Installing new switch packages <><><><><><><><><><><><><><><><><><><><><><>
Switch invariant: ["ocaml" {= "4.10.0"}]
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
∗ installed base-bigarray.base
∗ installed base-threads.base
∗ installed base-unix.base
[ERROR] User interruption
<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
┌─ The following actions failed
│ ⬇ fetch ocaml-base-compiler 4.10.0
└─
┌─ The following changes have been performed (the rest was aborted)
│ ∗ install base-bigarray base
│ ∗ install base-threads base
│ ∗ install base-unix base
└─
Switch initialisation failed: clean up? ('n' will leave the switch partially installed) [Y/n] y
$ ls _opam
ls: cannot access '_opam': No such file or directory
The use case was having created a switch on one branch, checking out a new branch, and trying to create a new switch.
E.g.
$ git checkout main
$ opam switch create .
$ git checkout v1.0
$ opam switch create.
[ERROR] There already is an installed switch named /dirpath
I've since realized opam switch remove . is the intended operation to remove the existing switch, instead of rf -f _opam. I think @avsm was suggesting appending a message like 'Use opam switch remove to remove it', interactively prompting the user whether to delete it, and/or a -f force flag to remove any existing switches when creating a new one.
Ok, I see better.
I'm wondering, on the process, @RyanGibb why/how did you get to create a new switch while you already had one?
From what I understand, you wanted the local switch to follow the branch change (related to #4984), why not use opam install or opam reinstall?
That sounds like a better solution than what we were doing! Apologies, I think this is just a case of me being unfamiliar with OCaml's tooling. Perhaps prompting the user to opam install/opam reinstall would be better a approach than what we suggested?
My use case probably only applies to Meta employees, but we have a related issue. I'd love to see a -f force option to ignore that the dir already exists.
We use Eden for our source control, which uses a virtual filesystem to download files on demand and track all local changes. Writing into _opam is very slow because of the overhead of tracking all the files, which is unnecessary since _opam will never be committed. Eden can mount directories from elsewhere on disk so writes to those folders are untracked.
But mount creates the directory, even though it's empty.
Here's a simple (but admittedly impulsive/careless) way how new users end up with a broken switch:
- User starts running someone else's instructions that happen to create a switch
- User realizes that they need to do a different step first, so they CTRL+C abort in the middle of installing the switch and proceed in the correct position of the instructions.
- Now, they have a broken switch and there's no hint on how to fix that when trying to create the switch again.
Saving grace is that searching the Internet for [ERROR] There already is an installed switch named brings you right to this issue, where you find the solution.
For this use case, either of the proposals mentioned by @RyanGibb (interactively prompting, or appending a message that gives a hint on how to remove the switch) would be helpful, as it means that the new user doesn't need to do an Internet search to resolve their issue.
What about prompting a link to a FAQ entry that summarises all cases (switch to remove and checkout new branch for the moment). The message will be cleaner and it is fast to update when a new case appears.
What about prompting a link to a FAQ entry that summarises all cases (switch to remove and checkout new branch for the moment). The message will be cleaner and it is fast to update when a new case appears.
That would be a big improvement for struggling new users, I think. The advantage of being able to update the FAQ without having to do a release is a strong point in favor of this solution.
That leaves @mroch's issue, which is separate from the new user experience.