Skip to content

Commit

Permalink
Reinstall plugin if symlink missing
Browse files Browse the repository at this point in the history
At present opam plugin will simply run opam-plugin if it is resolved in
the environment of the current switch.

Now $OPAMROOT/plugins/bin is checked for the required symlink. The
command is still resolved as normal, but the presence or not of the
symlink is used to control whether opam _installs_ the plugin package or
does a reinstall.

The reinstall both recreates the symlink and ensures that any changes to
the plugin have been picked up.
  • Loading branch information
dra27 authored and rjbou committed Apr 15, 2021
1 parent 8899856 commit 2c19103
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
1 change: 1 addition & 0 deletions master_changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ New option/command/subcommand are prefixed with ◈.
* Add cli versioning for opam environment variables [#4606 @rjbou]
* Deprecated `build-doc`, `build-test`, `make` [#4581 @rjbou]
* Add cli versioning for enums of flags with predefined enums [#4606 @rjbou]
* Ensure the symlink for a plugin is maintained on each invocation [#4621 @dra27 - partially fixes #4619]

## Init
* Introduce a `default-invariant` config field, restore the 2.0 semantics for
Expand Down
31 changes: 22 additions & 9 deletions src/client/opamCliMain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ let check_and_run_external_commands () =
let root_dir = OpamStateConfig.opamroot () in
let has_init = OpamStateConfig.load_defaults root_dir <> None in
let plugins_bin = OpamPath.plugins_bin root_dir in
let plugin_symlink_present =
OpamFilename.is_symlink (OpamPath.plugin_bin root_dir (OpamPackage.Name.of_string name))
in
let env =
if has_init then
let updates =
Expand All @@ -154,11 +157,11 @@ let check_and_run_external_commands () =
Unix.environment ()
in
match OpamSystem.resolve_command ~env command with
| Some command ->
| Some command when plugin_symlink_present ->
let argv = Array.of_list (command :: args) in
raise (OpamStd.Sys.Exec (command, argv, env))
| None when not has_init -> (cli, argv)
| None ->
| cmd ->
(* Look for a corresponding package *)
match OpamStateConfig.get_switch_opt () with
| None -> (cli, argv)
Expand All @@ -183,7 +186,7 @@ let check_and_run_external_commands () =
in
let installed = OpamPackage.Set.inter plugins st.installed in
if OpamPackage.Set.is_empty candidates then (cli, argv)
else if not OpamPackage.Set.(is_empty installed) then
else if not OpamPackage.Set.(is_empty installed) && cmd = None then
(OpamConsole.error
"Plugin %s is already installed, but no %s command was found.\n\
Try upgrading, and report to the package maintainer if \
Expand All @@ -205,18 +208,28 @@ let check_and_run_external_commands () =
then
let nv =
try
OpamPackage.max_version plugins
(OpamPackage.Name.of_string prefixed_name)
(* If the command was resolved, attempt to find the package to reinstall. *)
if cmd = None then
raise Not_found
else
OpamPackage.package_of_name installed (OpamPackage.Name.of_string prefixed_name)
with Not_found ->
OpamPackage.max_version plugins
(OpamPackage.Name.of_string name)
try
OpamPackage.max_version plugins
(OpamPackage.Name.of_string prefixed_name)
with Not_found ->
OpamPackage.max_version plugins
(OpamPackage.Name.of_string name)
in
OpamRepositoryConfig.init ();
OpamSolverConfig.init ();
OpamClientConfig.init ();
OpamSwitchState.with_ `Lock_write gt (fun st ->
OpamSwitchState.drop @@
OpamClient.install st [OpamSolution.eq_atom_of_package nv]
OpamSwitchState.drop @@ (
if cmd = None then
OpamClient.install st [OpamSolution.eq_atom_of_package nv]
else
OpamClient.reinstall st [OpamSolution.eq_atom_of_package nv])
);
match OpamSystem.resolve_command ~env command with
| None ->
Expand Down

0 comments on commit 2c19103

Please sign in to comment.