diff --git a/.github/workflows/ci.ml b/.github/workflows/ci.ml index 3aff647eb58..18285cc44b3 100644 --- a/.github/workflows/ci.ml +++ b/.github/workflows/ci.ml @@ -363,7 +363,7 @@ let main_build_job ~analyse_job ~cygwin_job ?section platform start_version ~oc ++ run "Build" ["bash -exu .github/scripts/main/main.sh " ^ host] ++ not_on Windows (run "Test (basic)" ["bash -exu .github/scripts/main/test.sh"]) ++ only_on Windows (run "Test (basic - Cygwin)" ~cond:(Predicate(true, EndsWith("matrix.host", "-pc-cygwin"))) ["bash -exu .github/scripts/main/test.sh"]) - ++ only_on Windows (run "Test (basic - native Windows)" ~shell:"cmd" ~cond:(Predicate(false, EndsWith("matrix.host", "-pc-cygwin"))) + ++ only_on Windows (run "Test (basic - native Windows)" ~env:[("OPAMROOT", {|D:\a\opam\opam\.opam|})] ~shell:"cmd" ~cond:(Predicate(false, EndsWith("matrix.host", "-pc-cygwin"))) ({|set Path=D:\Cache\ocaml-local\bin;%Path%|} :: {|if "${{ matrix.host }}" equ "x86_64-pc-windows" call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"|} :: {|if "${{ matrix.host }}" equ "i686-pc-windows" call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars32.bat"|} :: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ac7b5f56549..3de63492fbc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -246,6 +246,8 @@ jobs: if: endsWith(matrix.host, '-pc-cygwin') run: bash -exu .github/scripts/main/test.sh - name: Test (basic - native Windows) + env: + OPAMROOT: D:\a\opam\opam\.opam if: endsWith(matrix.host, '-pc-cygwin') == false shell: cmd run: | diff --git a/master_changes.md b/master_changes.md index 20ee3bdb852..06b3e646dce 100644 --- a/master_changes.md +++ b/master_changes.md @@ -37,6 +37,8 @@ users) ## Init * Run the sandbox check in the temporary directory [#4787 @dra27 - fix #4783] * [BUG] Fix `opam init` and `opam init --reinit` when the `jobs` variable has been set in the opamrc or the current config. [#5056 @rjbou] + * Use `.opam` from `%HOME%` or `%USERPROFILE%` on Windows, only if found; otherwise use `%LOCALAPPDATA%\opam` as root. [#5212 @dra27] + * Display actual location of OPAMROOT in `opam init` if `--root` or `OPAMROOT` have been set [#5212 @dra27 - fix #4992] ## Config report * [BUG] Don't fail is no switch is set [#5198 @rjbou] diff --git a/src/core/opamStd.ml b/src/core/opamStd.ml index 1d9e97f026c..e2ff181e9bd 100644 --- a/src/core/opamStd.ml +++ b/src/core/opamStd.ml @@ -850,7 +850,15 @@ module OpamSys = struct forcing the environment in this function that is used before the .init() functions are called -- see OpamStateConfig.default. *) - let home = lazy (try Unix.getenv "HOME" with Not_found -> Sys.getcwd ()) in + let home = lazy ( + try Unix.getenv "HOME" + with Not_found -> + if Sys.win32 then + (* CSIDL_PROFILE = 0x28 *) + OpamStubs.(shGetFolderPath 0x28 SHGFP_TYPE_CURRENT) + else + Sys.getcwd () + ) in fun () -> Lazy.force home let etc () = "/etc" diff --git a/src/state/opamEnv.ml b/src/state/opamEnv.ml index dba1250710a..575a0484b4d 100644 --- a/src/state/opamEnv.ml +++ b/src/state/opamEnv.ml @@ -798,6 +798,14 @@ let check_and_print_env_warning st = let setup root ~interactive ?dot_profile ?update_config ?env_hook ?completion ?inplace shell = + let opam_root_msg = + let current = OpamFilename.prettify_dir root in + if root = OpamStateConfig.(default.root_dir) then + current + else + let default = OpamFilename.prettify_dir OpamStateConfig.(default.root_dir) in + Printf.sprintf "your opam root\n (%s by default; currently %s)" default current + in let shell, update_dot_profile, env_hook = match update_config, dot_profile, interactive with | Some false, _, _ -> shell, None, env_hook @@ -809,7 +817,7 @@ let setup OpamConsole.msg "\n\ - \ In normal operation, opam only alters files within ~%s.opam.\n\ + \ In normal operation, opam only alters files within %s.\n\ \n\ \ However, to best integrate with your system, some environment variables\n\ \ should be set. If you allow it to, this initialisation step will update\n\ @@ -818,7 +826,7 @@ let setup \ %s\ \n\ \ You can always re-run this setup with 'opam init' later.\n\n" - Filename.dir_sep + opam_root_msg (OpamConsole.colorise `bold @@ string_of_shell shell) (OpamConsole.colorise `cyan @@ OpamFilename.prettify dot_profile) (OpamConsole.colorise `bold @@ source root shell (init_file shell)); diff --git a/src/state/opamStateConfig.ml b/src/state/opamStateConfig.ml index 8d4540c83fc..455e28a7658 100644 --- a/src/state/opamStateConfig.ml +++ b/src/state/opamStateConfig.ml @@ -70,8 +70,22 @@ type t = { } let default = { - root_dir = OpamFilename.( + root_dir = ( + (* On Windows, if a .opam directory is found in %HOME% or %USERPROFILE% then + then we'll use it. Otherwise, we use %LOCALAPPDATA%. *) + let home_location = + let open OpamFilename in concat_and_resolve (Dir.of_string (OpamStd.Sys.home ())) ".opam" + in + if not Sys.win32 || OpamFilename.exists_dir home_location then + home_location + else + let open OpamFilename in + let local_appdata = + (* CSIDL_LOCAL_APPDATA = 0x1c *) + Dir.of_string (OpamStubs.(shGetFolderPath 0x1c SHGFP_TYPE_CURRENT)) + in + concat_and_resolve local_appdata "opam" ); current_switch = None; switch_from = `Default; diff --git a/src/state/opamStateConfig.mli b/src/state/opamStateConfig.mli index f14dbe24000..4e118103369 100644 --- a/src/state/opamStateConfig.mli +++ b/src/state/opamStateConfig.mli @@ -76,6 +76,9 @@ include OpamStd.Config.Sig with type t := t and type 'a options_fun := 'a options_fun +(** Default state values *) +val default : t + (** Get the initial opam root value (from default, env or optional argument). This allows one to get it before doing the init, which is useful to get the configuration file used to fill some options to init() *)