diff --git a/.github/workflows/ci.ml b/.github/workflows/ci.ml index c10a95b7864..8bf9b0673ad 100644 --- a/.github/workflows/ci.ml +++ b/.github/workflows/ci.ml @@ -360,7 +360,7 @@ let main_test_job ~analyse_job ~build_linux_job ~build_windows_job:_ ~build_macO let host = host_of_platform platform in let ocamlv = "${{ matrix.ocamlv }}" in job ~oc ~workflow ?section ~runs_on:(Runner [runner]) ~env:[("OPAM_TEST", "1")] ~matrix ~needs ("Test-" ^ name_of_platform platform) - ++ only_on MacOS (install_sys_packages ["coreutils"] ~descr:"Install gnu coreutils" [MacOS]) + ++ only_on MacOS (install_sys_packages ["coreutils"; "gpatch"] ~descr:"Install gnu coreutils" [MacOS]) ++ checkout () ++ only_on Linux (run "Install bubblewrap" ["sudo apt install bubblewrap"]) ++ cache Archives diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 413f121d7c7..c996928f85a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -322,7 +322,7 @@ jobs: OPAM_TEST: 1 steps: - name: Install gnu coreutils - run: brew install coreutils + run: brew install coreutils gpatch - name: Checkout tree uses: actions/checkout@v4 - name: src_ext/archives and opam-repository Cache diff --git a/master_changes.md b/master_changes.md index bd0842b5638..32fd3c7346f 100644 --- a/master_changes.md +++ b/master_changes.md @@ -31,6 +31,7 @@ users) * Simplify computation of OCaml init default `sys-ocaml-*` eval variables on Unix [#5829 @dra27] * Add a init OCaml `sys-ocaml-system` eval variable [#5829 @dra27] * Mark the internal cygwin installation as recommended [#5903 @kit-ty-kate] + * Check for gpatch instead of patch on NetBSD and DragonFlyBSD [#5893 @kit-ty-kate] ## Config report @@ -65,6 +66,7 @@ users) * Add warning 69: Warn for new syntax when package name in variable in string interpolation contains several '+' [#5840 @rjbou] ## Repository + * Warn if `GNU patch` is not detected during a repository update [#5893 @kit-ty-kate] ## Lock @@ -126,6 +128,9 @@ users) * 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 + * Warn if `GNU patch` is not detected when a patch is applied [#5893 @kit-ty-kate] + * Use `gpatch` by default instead of `patch` on NetBSD and DragonFlyBSD [#5893 @kit-ty-kate] + * Use `gpatch` if it exists and is detected as GNU patch when `patch` is not `GNU patch` [#5893 @kit-ty-kate] ## Internal: Windows * Ensure that the system critical error dialog is disabled when opam starts [#5828 @dra27] @@ -191,3 +196,4 @@ users) ## opam-core * `OpamStd.Sys`: add `is_cygwin_variant_cygcheck` that returns true if in path `cygcheck` is from a Cygwin or MSYS2 installation [#5843 @rjbou] * `OpamStd.Env.cyg_env`: takes the environment to cygify, usually `OpamStd.Env.raw_env` [#5829 @dra27] + * `OpamSystem.patch` now displays a warning when GNU patch is not detected and looks for both patch and gpatch as a backup option depending on the OS [#5893 @kit-ty-kate] diff --git a/src/client/opamInitDefaults.ml b/src/client/opamInitDefaults.ml index 0c960246526..608ac078fb7 100644 --- a/src/client/opamInitDefaults.ml +++ b/src/client/opamInitDefaults.ml @@ -46,6 +46,8 @@ let linux_filter = os_filter "linux" let macos_filter = os_filter "macos" let openbsd_filter = os_filter "openbsd" let freebsd_filter = os_filter "freebsd" +let netbsd_filter = os_filter "netbsd" +let dragonflybsd_filter = os_filter "dragonfly" let not_open_free_bsd_filter = FNot (FOr (openbsd_filter, freebsd_filter)) let win32_filter = os_filter "win32" @@ -53,7 +55,9 @@ let not_win32_filter = FOp (FIdent ([], OpamVariable.of_string "os", None), `Neq, FString "win32") let sandbox_filter = FOr (linux_filter, macos_filter) -let gpatch_filter = FOr (openbsd_filter, freebsd_filter) +let gpatch_filter = + FOr (FOr (openbsd_filter, netbsd_filter), + FOr (freebsd_filter, dragonflybsd_filter)) let patch_filter = FNot gpatch_filter let gtar_filter = openbsd_filter diff --git a/src/core/opamSystem.ml b/src/core/opamSystem.ml index cd4169ccd9d..d75bf3961d9 100644 --- a/src/core/opamSystem.ml +++ b/src/core/opamSystem.ml @@ -1633,6 +1633,40 @@ let translate_patch ~dir orig corrected = end; close_in ch +let gpatch = lazy begin + let rec search_gpatch = function + | [] -> None + | patch_cmd::patch_cmds -> + match OpamProcess.run (make_command ~name:"patch" patch_cmd ["--version"]) with + | r -> + (match OpamProcess.is_success r, r.OpamProcess.r_stdout with + | true, full::_ when + OpamStd.String.is_prefix_of ~from:0 ~full "GNU patch " -> + Some patch_cmd + | _ -> + search_gpatch patch_cmds) + | exception _ -> search_gpatch patch_cmds + in + let default_cmd, other_cmds = + match OpamStd.Sys.os () with + | DragonFly + | FreeBSD + | NetBSD + | OpenBSD -> ("gpatch", ["patch"]) + | Cygwin + | Darwin + | Linux + | Unix + | Win32 + | Other _ -> ("patch", ["gpatch"]) + in + match search_gpatch (default_cmd :: other_cmds) with + | Some gpatch -> gpatch + | None -> + OpamConsole.warning "Invalid patch utility. Please install GNU patch"; + default_cmd +end + let patch ?(preprocess=true) ~dir p = if not (Sys.file_exists p) then (OpamConsole.error "Patch file %S not found." p; @@ -1645,12 +1679,7 @@ let patch ?(preprocess=true) ~dir p = else p in - let patch_cmd = - match OpamStd.Sys.os () with - | OpamStd.Sys.OpenBSD - | OpamStd.Sys.FreeBSD -> "gpatch" - | _ -> "patch" - in + let patch_cmd = Lazy.force gpatch in make_command ~name:"patch" ~dir patch_cmd ["-p1"; "-i"; p'] @@> fun r -> if not (OpamConsole.debug ()) then Sys.remove p'; if OpamProcess.is_success r then Done None diff --git a/tests/reftests/repository.test b/tests/reftests/repository.test index 3e087df0333..d061daf40d1 100644 --- a/tests/reftests/repository.test +++ b/tests/reftests/repository.test @@ -8,6 +8,7 @@ some content ### opam switch create tarring --empty ### opam update -vv | grep '^\+' | sed-cmd diff | sed-cmd patch | 'patch-[^"]+' -> 'patch' + diff "-ruaN" "default" "default.new" (CWD=${BASEDIR}/OPAM/repo) ++ patch "--version" + patch "-p1" "-i" "${BASEDIR}/OPAM/log/patch" (CWD=${BASEDIR}/OPAM/repo/default) ### ls $OPAMROOT/repo | grep -v "cache" default @@ -26,6 +27,7 @@ build: ["test" "-f" "baz"] some content ### opam update default -vv | grep '^\+' | sed-cmd tar | sed-cmd diff | sed-cmd patch | 'patch-[^"]+' -> 'patch' + diff "-ruaN" "default" "default.new" (CWD=${BASEDIR}/OPAM/repo) ++ patch "--version" + patch "-p1" "-i" "${BASEDIR}/OPAM/log/patch" (CWD=${BASEDIR}/OPAM/repo/default) + tar "cfz" "${BASEDIR}/OPAM/repo/default.tar.gz.tmp" "-C" "${BASEDIR}/OPAM/repo" "default" ### ls $OPAMROOT/repo | grep -v "cache" @@ -64,6 +66,7 @@ some content ### opam update -vv | grep '^\+' | sed-cmd tar | sed-cmd diff | sed-cmd patch | 'patch-[^"]+' -> 'patch' + tar "xfz" "${BASEDIR}/OPAM/repo/tarred.tar.gz" "-C" "${OPAMTMP}" + diff "-ruaN" "tarred" "tarred.new" (CWD=${OPAMTMP}) ++ patch "--version" + patch "-p1" "-i" "${BASEDIR}/OPAM/log/patch" (CWD=${OPAMTMP}/tarred) + tar "cfz" "${BASEDIR}/OPAM/repo/tarred.tar.gz.tmp" "-C" "${OPAMTMP}" "tarred" ### opam install foo.4 -vv | grep '^\+' | sed-cmd test | sed-cmd tar @@ -86,6 +89,7 @@ some content ### opam update -vv | grep '^\+' | sed-cmd tar | sed-cmd diff | sed-cmd patch | 'patch-[^"]+' -> 'patch' + tar "xfz" "${BASEDIR}/OPAM/repo/tarred.tar.gz" "-C" "${OPAMTMP}" + diff "-ruaN" "tarred" "tarred.new" (CWD=${OPAMTMP}) ++ patch "--version" + patch "-p1" "-i" "${BASEDIR}/OPAM/log/patch" (CWD=${OPAMTMP}/tarred) ### opam install foo.5 -vv | grep '^\+' | sed-cmd test + test "-f" "quux" (CWD=${BASEDIR}/OPAM/tarring/.opam-switch/build/foo.5)