diff --git a/master_changes.md b/master_changes.md index 8d07447fb8e..0b06f08639f 100644 --- a/master_changes.md +++ b/master_changes.md @@ -63,6 +63,7 @@ users) * Fix shell detection on Windows when opam is called via Cygwin's /usr/bin/env even though cmd/powershell is used [#5797 @kit-ty-kate] * Fix incorrect deduplication of environment variables on update. Effect was that FOO += "" would occlude the value of FOO in the environment [#5837 @dra27] * Fix regression from #5356 on the detection of out-of-date environment variables. As part of a refactoring, a filter predicate got inverted [#5837 @dra27] + * Unixify Windows paths in init shells scripts (sh, bash, zsh, fish & tsh) [#5797 @rjbou] ## Opamfile @@ -101,6 +102,7 @@ users) ## Client ## Shell + * Quote all the paths to OPAMROOT when creating the init scripts on Unix in case OPAMROOT contains spaces, backslashes or special characters [#5841 @kit-ty-kate - fix #5804] ## Internal diff --git a/src/core/opamSystem.mli b/src/core/opamSystem.mli index 4023da622cf..de977c51c0d 100644 --- a/src/core/opamSystem.mli +++ b/src/core/opamSystem.mli @@ -202,8 +202,7 @@ val get_cygpath_function: command:string -> (string -> string) lazy_t val get_cygpath_path_transform: (pathlist:bool -> string -> string) lazy_t (** [apply_cygpath path] applies the `cygpath` command to [name] using - `cygpath -- name`. `cygpath` is resolved with default environment - in the function. *) + `cygpath -- name`. *) val apply_cygpath: string -> string (** [command cmd] executes the command [cmd] in the correct OPAM diff --git a/src/state/opamEnv.ml b/src/state/opamEnv.ml index 58f3dccb85c..42f4a30889e 100644 --- a/src/state/opamEnv.ml +++ b/src/state/opamEnv.ml @@ -875,16 +875,26 @@ let env_hook_script shell = let source root shell f = let fname = OpamFilename.to_string (OpamPath.init root // f) in + let unix_transform ?using_backslashes () = + let cygpath = Lazy.force OpamSystem.get_cygpath_path_transform in + cygpath ~pathlist:false fname + |> OpamStd.Env.escape_single_quotes ?using_backslashes + in match shell with | SH_csh -> - Printf.sprintf "if ( -f %s ) source %s >& /dev/null\n" fname fname + let fname = unix_transform () in + Printf.sprintf "if ( -f '%s' ) source '%s' >& /dev/null\n" + fname fname | SH_fish -> - Printf.sprintf "source %s > /dev/null 2> /dev/null; or true\n" fname + let fname = unix_transform ~using_backslashes:true () in + Printf.sprintf "source '%s' > /dev/null 2> /dev/null; or true\n" fname | SH_sh | SH_bash -> - Printf.sprintf "test -r %s && . %s > /dev/null 2> /dev/null || true\n" + let fname = unix_transform () in + Printf.sprintf "test -r '%s' && . '%s' > /dev/null 2> /dev/null || true\n" fname fname | SH_zsh -> - Printf.sprintf "[[ ! -r %s ]] || source %s > /dev/null 2> /dev/null\n" + let fname = unix_transform () in + Printf.sprintf "[[ ! -r '%s' ]] || source '%s' > /dev/null 2> /dev/null\n" fname fname | SH_cmd -> Printf.sprintf "if exist \"%s\" call \"%s\" >NUL 2>NUL\n" fname fname