diff --git a/.github/scripts/hygiene.sh b/.github/scripts/hygiene.sh index d189cf9377d..5dd5061ef4f 100644 --- a/.github/scripts/hygiene.sh +++ b/.github/scripts/hygiene.sh @@ -67,12 +67,15 @@ case $GITHUB_EVENT_NAME in CheckConfigure "$GITHUB_SHA" ;; pull_request) - for commit in $(git rev-list $BASE_REF_SHA...$PR_REF_SHA --reverse) - do - echo "check configure for $commit" - CheckConfigure "$commit" - done + CheckConfigure "$PR_REF_SHA" ;; + #git rev-list $BASE_REF_SHA...$PR_REF_SHA --reverse + #for commit in $(git rev-list $BASE_REF_SHA...$PR_REF_SHA --reverse) + #do + # echo "check configure for $commit" + # CheckConfigure "$commit" + #done + #;; *) echo "no configure to check for unknown event" ;; diff --git a/CHANGES b/CHANGES index 0ae406b6a6f..47814833b14 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,17 @@ repositories (changes that are automatically handled by the format upgrade tools are not marked). Those prefixed with "(+)" are new command/option (since 2.1.0~alpha2). +2.1.5: +* [BUG] Variables are now expanded in build-env (as for setenv) [#5352 @dra27] +* Correctly handle empty environment variable additions [#5350 @dra27] +* Skip empty environment variable additions [#5350 @dra27] +* [BUG] Fix passing `archive-mirrors` field from init config file to config + [#5315 @hannesm] +* git, hg: Use the full SHA1 revision instead of just the 8 first characters + [#5342 @reynir] +* [BUG] Fix opam installing packages without checking their checksum when the + local cache is corrupted in some case [#5538 @kit-ty-kate] + 2.1.4: * Add support for OCaml 5.0. Dose3 >= 6.1 and base64 >= 3.1.0 are now required [#5357 @kit-ty-kate @dra27 - fix #5354] * [BUG] Fix all empty conflict explanation messages [#5378 @kit-ty-kate - partial fix #4373] diff --git a/configure b/configure index 8e0d3f6edfb..3ef9f63487b 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for opam 2.1.4. +# Generated by GNU Autoconf 2.71 for opam 2.1.5. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, @@ -609,8 +609,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='opam' PACKAGE_TARNAME='opam' -PACKAGE_VERSION='2.1.4' -PACKAGE_STRING='opam 2.1.4' +PACKAGE_VERSION='2.1.5' +PACKAGE_STRING='opam 2.1.5' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1330,7 +1330,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures opam 2.1.4 to adapt to many kinds of systems. +\`configure' configures opam 2.1.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1392,7 +1392,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of opam 2.1.4:";; + short | recursive ) echo "Configuration of opam 2.1.5:";; esac cat <<\_ACEOF @@ -1502,7 +1502,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -opam configure 2.1.4 +opam configure 2.1.5 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1699,7 +1699,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by opam $as_me 2.1.4, which was +It was created by opam $as_me 2.1.5, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -7479,7 +7479,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by opam $as_me 2.1.4, which was +This file was extended by opam $as_me 2.1.5, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7534,7 +7534,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -opam config.status 2.1.4 +opam config.status 2.1.5 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index f6a64113ffa..3df29fec7e9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ dnl The line below must be formatted AC_INIT(opam,VERSION) with no extra spaces -AC_INIT(opam,2.1.4) +AC_INIT(opam,2.1.5) AC_COPYRIGHT(Copyright 2012-2019 OcamlPro SAS) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/pages/Manual.md b/doc/pages/Manual.md index df3d267e046..d63a62a11fe 100644 --- a/doc/pages/Manual.md +++ b/doc/pages/Manual.md @@ -644,6 +644,10 @@ other system). by opam, the new value will replace the old one at the same position instead of being put in front. +`FOO = ""` causes `FOO` to be set _but empty_ on Unix but _unset_ on Windows. + +`FOO += ""`, `FOO := ""`, etc. are all ignored - i.e. opam never adds empty segments to an existing variable. + ### URLs URLs are provided as strings. They can refer to: diff --git a/opam-client.opam b/opam-client.opam index 0b4a6378193..b6ab961a780 100644 --- a/opam-client.opam +++ b/opam-client.opam @@ -1,5 +1,5 @@ opam-version: "2.0" -version: "2.1.4" +version: "2.1.5" synopsis: "Client library for opam 2.1" description: """ Actions on the opam root, switches, installations, and front-end. diff --git a/opam-core.opam b/opam-core.opam index f3880b21d7d..81f35075904 100644 --- a/opam-core.opam +++ b/opam-core.opam @@ -1,5 +1,5 @@ opam-version: "2.0" -version: "2.1.4" +version: "2.1.5" synopsis: "Core library for opam 2.1" description: """ Small standard library extensions, and generic system interaction modules used by opam. diff --git a/opam-devel.opam b/opam-devel.opam index ddbd5b51ef7..347bdbd40b7 100644 --- a/opam-devel.opam +++ b/opam-devel.opam @@ -1,5 +1,5 @@ opam-version: "2.0" -version: "2.1.4" +version: "2.1.5" synopsis: "Bootstrapped development binary for opam 2.1" description: """ This package compiles (bootstraps) opam. For consistency and safety of the installation, the binaries are not installed into the PATH, but into lib/opam-devel, from where the user can manually install them system-wide. diff --git a/opam-format.opam b/opam-format.opam index 7b25e1cf66c..b956105eb25 100644 --- a/opam-format.opam +++ b/opam-format.opam @@ -1,5 +1,5 @@ opam-version: "2.0" -version: "2.1.4" +version: "2.1.5" synopsis: "Format library for opam 2.1" description: """ Definition of opam datastructures and its file interface. diff --git a/opam-installer.opam b/opam-installer.opam index e3e2c71dfe9..1f40ebbe0fe 100644 --- a/opam-installer.opam +++ b/opam-installer.opam @@ -1,5 +1,5 @@ opam-version: "2.0" -version: "2.1.4" +version: "2.1.5" synopsis: "Installation of files to a prefix, following opam conventions" description: """ opam-installer is a small tool that can read *.install files, as defined by opam [1], and execute them to install or remove package files without going through opam. diff --git a/opam-repository.opam b/opam-repository.opam index 8771a8c184c..4a8b14cfcf8 100644 --- a/opam-repository.opam +++ b/opam-repository.opam @@ -1,5 +1,5 @@ opam-version: "2.0" -version: "2.1.4" +version: "2.1.5" synopsis: "Repository library for opam 2.1" description: """ This library includes repository and remote sources handling, including curl/wget, rsync, git, mercurial, darcs backends. diff --git a/opam-solver.opam b/opam-solver.opam index 8818054e6bb..acb5318a869 100644 --- a/opam-solver.opam +++ b/opam-solver.opam @@ -1,5 +1,5 @@ opam-version: "2.0" -version: "2.1.4" +version: "2.1.5" synopsis: "Solver library for opam 2.1" description: """ Solver and Cudf interaction. This library is based on the Cudf and Dose libraries, and handles calls to the external solver from opam. diff --git a/opam-state.opam b/opam-state.opam index 6b3595957df..6c4c67402b0 100644 --- a/opam-state.opam +++ b/opam-state.opam @@ -1,5 +1,5 @@ opam-version: "2.0" -version: "2.1.4" +version: "2.1.5" synopsis: "State library for opam 2.1" description: """ Handling of the ~/.opam hierarchy, repository and switch states. diff --git a/opam.opam b/opam.opam index e5611c0bf32..1d0daa644c4 100644 --- a/opam.opam +++ b/opam.opam @@ -1,5 +1,5 @@ opam-version: "2.0" -version: "2.1.4" +version: "2.1.5" synopsis: "Meta-package for Dune" maintainer: "opam-devel@lists.ocaml.org" authors: [ diff --git a/src/client/opamAction.ml b/src/client/opamAction.ml index 4e9642b3ae4..159b17175d9 100644 --- a/src/client/opamAction.ml +++ b/src/client/opamAction.ml @@ -479,6 +479,9 @@ let prepare_package_source st nv dir = let compilation_env t opam = let open OpamParserTypes in + let build_env = + List.map (OpamEnv.env_expansion ~opam t) (OpamFile.OPAM.build_env opam) + in let scrub = OpamClientConfig.(!r.scrubbed_environment_variables) in OpamEnv.get_full ~scrub ~set_opamroot:true ~set_opamswitch:true ~force_path:true t ~updates:([ @@ -493,7 +496,7 @@ let compilation_env t opam = Some "build environment definition"; "OPAMCLI", Eq, "2.0", Some "opam CLI version"; ] @ - OpamFile.OPAM.build_env opam) + build_env) let installed_opam_opt st nv = OpamStd.Option.Op.( diff --git a/src/client/opamClient.ml b/src/client/opamClient.ml index 36c2709c006..c4a5a800edc 100644 --- a/src/client/opamClient.ml +++ b/src/client/opamClient.ml @@ -756,6 +756,7 @@ let update_with_init_config ?(overwrite=false) config init_config = | Some j -> setifnew C.jobs C.with_jobs j | None -> fun c -> c) |> setifnew C.dl_tool C.with_dl_tool_opt (I.dl_tool init_config) |> + setifnew C.dl_cache C.with_dl_cache (I.dl_cache init_config) |> setifnew C.dl_jobs C.with_dl_jobs (OpamStd.Option.default OpamStateConfig.(default.dl_jobs) (I.dl_jobs init_config)) |> diff --git a/src/repository/opamGit.ml b/src/repository/opamGit.ml index 9af216c9f71..563c3a7660c 100644 --- a/src/repository/opamGit.ml +++ b/src/repository/opamGit.ml @@ -157,10 +157,7 @@ module VCS : OpamVCS.VCS = struct match r.OpamProcess.r_stdout with | [] -> Done None | full::_ -> - if String.length full > 8 then - Done (Some (String.sub full 0 8)) - else - Done (Some full)) + Done (Some full)) let clean repo_root = git repo_root [ "clean"; "-fdx" ] diff --git a/src/repository/opamHg.ml b/src/repository/opamHg.ml index bb40719b64d..0ee41ff4398 100644 --- a/src/repository/opamHg.ml +++ b/src/repository/opamHg.ml @@ -53,8 +53,7 @@ module VCS = struct match r.OpamProcess.r_stdout with | [] -> Done None | full::_ -> - if String.length full > 8 then Done (Some (String.sub full 0 8)) - else Done (Some full) + Done (Some full) let clean repo_root = hg repo_root ["revert"; "--all"; "--no-backup"] diff --git a/src/repository/opamRepository.ml b/src/repository/opamRepository.ml index b20a3819c8b..0dce42652d6 100644 --- a/src/repository/opamRepository.ml +++ b/src/repository/opamRepository.ml @@ -93,15 +93,14 @@ let fetch_from_cache = failwith "Version control not allowed as cache URL" in try - let hit_checksum, hit_file = + let hit_file = OpamStd.List.find_map (fun ck -> let f = cache_file cache_dir ck in - if OpamFilename.exists f then Some (ck, f) else None) + if OpamFilename.exists f then Some f else None) checksums in if List.for_all - (fun ck -> ck = hit_checksum || - OpamHash.check_file (OpamFilename.to_string hit_file) ck) + (fun ck -> OpamHash.check_file (OpamFilename.to_string hit_file) ck) checksums then Done (Up_to_date (hit_file, OpamUrl.empty)) else mismatch hit_file diff --git a/src/state/opamEnv.ml b/src/state/opamEnv.ml index 9237e417078..3fd436a7721 100644 --- a/src/state/opamEnv.ml +++ b/src/state/opamEnv.ml @@ -40,19 +40,19 @@ let unzip_to elt current = | ([], rs) -> Some rs | _ -> None in - match split_var elt with - | [] -> invalid_arg "OpamEnv.unzip_to" - | hd::tl -> - let rec aux acc = function + match (if elt = "" then [""] else split_var elt) with + | [] -> invalid_arg "OpamEnv.unzip_to" + | hd::tl -> + let rec aux acc = function | [] -> None | x::r -> - if x = hd then + if (x : string) = hd then match remove_prefix tl r with | Some r -> Some (acc, r) | None -> aux (x::acc) r else aux (x::acc) r - in - aux [] current + in + aux [] current let rezip ?insert (l1, l2) = List.rev_append l1 (match insert with None -> l2 | Some i -> i::l2) @@ -91,6 +91,7 @@ let apply_op_zip op arg (rl1,l2 as zip) = or empty lists is returned if the variable should be unset or has an unknown previous value. *) let reverse_env_update op arg cur_value = + if arg = "" && op <> Eq then None else match op with | Eq -> if arg = join_var cur_value @@ -157,9 +158,13 @@ let expand (updates: env_update list) : env = | Some s -> ([], split_var s), reverts | None -> ([], []), reverts in + let acc = + if arg = "" && op <> Eq then acc else + ((var, apply_op_zip op arg zip, doc) :: acc) + in apply_updates reverts - ((var, apply_op_zip op arg zip, doc) :: acc) + acc updates | [] -> List.rev @@ @@ -185,18 +190,22 @@ let add (env: env) (updates: env_update list) = in env @ expand updates +let env_expansion ?opam st (name, op, str, cmt) = + let fenv v = + try OpamPackageVar.resolve st ?opam v + with Not_found -> + log "Undefined variable: %s" (OpamVariable.Full.to_string v); + None + in + let s = OpamFilter.expand_string ~default:(fun _ -> "") fenv str in + name, op, s, cmt + let compute_updates ?(force_path=false) st = (* Todo: put these back into their packages! let perl5 = OpamPackage.Name.of_string "perl5" in let add_to_perl5lib = OpamPath.Switch.lib t.root t.switch t.switch_config perl5 in let new_perl5lib = "PERL5LIB", "+=", OpamFilename.Dir.to_string add_to_perl5lib in *) - let fenv ?opam v = - try OpamPackageVar.resolve st ?opam v - with Not_found -> - log "Undefined variable: %s" (OpamVariable.Full.to_string v); - None - in let bindir = OpamPath.Switch.bin st.switch_global.root st.switch st.switch_config in @@ -218,21 +227,17 @@ let compute_updates ?(force_path=false) st = st.switch_global.root st.switch st.switch_config), Some "Current opam switch man dir"] in - let env_expansion ?opam (name,op,str,cmt) = - let s = OpamFilter.expand_string ~default:(fun _ -> "") (fenv ?opam) str in - name, op, s, cmt - in let switch_env = ("OPAM_SWITCH_PREFIX", Eq, OpamFilename.Dir.to_string (OpamPath.Switch.root st.switch_global.root st.switch), Some "Prefix of the current opam switch") :: - List.map env_expansion st.switch_config.OpamFile.Switch_config.env + List.map (env_expansion st) st.switch_config.OpamFile.Switch_config.env in let pkg_env = (* XXX: Does this need a (costly) topological sort? *) OpamPackage.Set.fold (fun nv acc -> match OpamPackage.Map.find_opt nv st.opams with - | Some opam -> List.map (env_expansion ~opam) (OpamFile.OPAM.env opam) @ acc + | Some opam -> List.map (env_expansion ~opam st) (OpamFile.OPAM.env opam) @ acc | None -> acc) st.installed [] in diff --git a/src/state/opamEnv.mli b/src/state/opamEnv.mli index 5d99d02764a..c0aaa0bc793 100644 --- a/src/state/opamEnv.mli +++ b/src/state/opamEnv.mli @@ -94,6 +94,9 @@ val path: force_path:bool -> dirname -> switch -> string val full_with_path: force_path:bool -> ?updates:env_update list -> dirname -> switch -> env +(** Performs variable expansion on the strings in an environment update *) +val env_expansion: ?opam:OpamFile.OPAM.t -> 'a switch_state -> env_update -> env_update + (** {2 Shell and initialisation support} *) (** Sets the opam configuration in the user shell, after detailing the process diff --git a/tests/reftests/dune.inc b/tests/reftests/dune.inc index dada36be5ab..be4b1b37227 100644 --- a/tests/reftests/dune.inc +++ b/tests/reftests/dune.inc @@ -376,6 +376,23 @@ %{targets} (run ./run.exe %{bin:opam} %{dep:list.unix.test} %{read-lines:testing-env})))) +(alias + (name reftest-local-cache) + (action + (diff local-cache.test local-cache.out))) + +(alias + (name reftest) + (deps (alias reftest-local-cache))) + +(rule + (targets local-cache.out) + (deps root-N0REP0) + (action + (with-stdout-to + %{targets} + (run ./run.exe %{bin:opam} %{dep:local-cache.test} %{read-lines:testing-env})))) + (alias (name reftest-opamroot-versions) (action diff --git a/tests/reftests/env.test b/tests/reftests/env.test index 68baafd6bc6..fb7529f67e5 100644 --- a/tests/reftests/env.test +++ b/tests/reftests/env.test @@ -50,3 +50,73 @@ NV_VARS=''; export NV_VARS; NV_VARS=hej!! OPAM=${OPAM} OPAM_SWITCH_PREFIX=${BASEDIR}/OPAM/conffile +### : Buil environment variable expansion : +### +opam-version: "2.0" +build: [ "sh" "-c" "echo V$BDE_VERSION > pkg.version" ] +install: [ "cp" "pkg.version" "%{doc}%/pkg.version" ] +build-env: [ BDE_VERSION = "%{version}%" ] +### opam switch create build-env --empty +### opam install bde +The following actions will be performed: + - install bde 1.2.3 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed bde.1.2.3 +Done. +### cat $OPAMROOT/build-env/doc/pkg.version +V1.2.3 +### : empty environment variables update : +### NV_VARS='' +### +opam-version: "2.0" +setenv: [ + [ NV_VARS += "" ] + [ NV_VARS2 := "" ] + [ NV_VARS3 := "" ] + [ NV_VARS3 := "foo" ] + [ NV_VARS4 = "" ] +] +flags: compiler +### opam switch create emptyvar nv + +<><> Installing new switch packages <><><><><><><><><><><><><><><><><><><><><><> +Switch invariant: ["nv"] + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed nv.1 +Done. +### opam env | grep "NV_VARS" | ';' -> ':' +NV_VARS3='foo:': export NV_VARS3: +NV_VARS4='': export NV_VARS4: +### opam exec -- opam env --revert | grep "NV_VARS" | ';' -> ':' +NV_VARS3='': export NV_VARS3: +NV_VARS4='': export NV_VARS4: +### NV_VARS=/another/path +### NV_VARS2=/another/different/path +### NV_VARS3=/yet/another/different/path +### NV_VARS4=ignored-value +### opam env | grep "NV_VARS" | ';' -> ':' +NV_VARS3='foo:/yet/another/different/path': export NV_VARS3: +NV_VARS4='': export NV_VARS4: +### opam exec -- opam env --revert | grep "NV_VARS" | ';' -> ':' +NV_VARS3='/yet/another/different/path': export NV_VARS3: +NV_VARS4='': export NV_VARS4: +### : root and switch with spaces : +### RT="$BASEDIR/root 2" +### SW="switch w spaces" +### OPAMNOENVNOTICE=0 +### opam init -na --bare --bypass-check --disable-sandbox --root "$RT" defaut ./REPO +No configuration file found, using built-in defaults. + +<><> Fetching repository information ><><><><><><><><><><><><><><><><><><><><><> +[defaut] Initialised +### opam switch create "./$SW" nv --root "$RT" + +<><> Installing new switch packages <><><><><><><><><><><><><><><><><><><><><><> +Switch invariant: ["nv"] + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed nv.1 +Done. +# Run eval $(opam env --root=${BASEDIR}/root 2 --switch=${BASEDIR}/switch w spaces) to update the current shell environment diff --git a/tests/reftests/init.test b/tests/reftests/init.test index 9d0d7df8e9c..9768567dc1a 100644 --- a/tests/reftests/init.test +++ b/tests/reftests/init.test @@ -90,3 +90,156 @@ Faking installation of ocaml-base-compiler.4.10.0 Faking installation of ocaml-config.1 Faking installation of ocaml.4.10.0 Done. +### : Init with config file : +### +opam-version: "2.0" +### +opam-version: "2.0" +### :: default setup :: +### rm -rf $OPAMROOT +### opam init --bypass-checks --bare --no-setup default REPO/ +No configuration file found, using built-in defaults. + +<><> Fetching repository information ><><><><><><><><><><><><><><><><><><><><><> +[default] Initialised +### opam-cat $OPAMROOT/config +default-compiler: ["ocaml-system" "ocaml-base-compiler"] +default-invariant: ["ocaml" {>= "4.05.0"}] +depext: true +depext-cannot-install: false +depext-run-installs: true +download-jobs: 3 +eval-variables: [[sys-ocaml-version ["ocamlc" "-vnum"] "OCaml version present on your system independently of opam, if any"] [sys-ocaml-arch ["sh" "-c" "ocamlc -config 2>/dev/null | tr -d '/r' | grep '^architecture: ' | sed -e 's/.*: //' -e 's/i386/i686/' -e 's/amd64/x86_64/'"] "Target architecture of the OCaml compiler present on your system"] [sys-ocaml-cc ["sh" "-c" "ocamlc -config 2>/dev/null | tr -d '/r' | grep '^ccomp_type: ' | sed -e 's/.*: //'"] "Host C Compiler type of the OCaml compiler present on your system"] [sys-ocaml-libc ["sh" "-c" "ocamlc -config 2>/dev/null | tr -d '/r' | grep '^os_type: ' | sed -e 's/.*: //' -e 's/Win32/msvc/' -e '/^msvc$/!s/.*/libc/'"] "Host C Runtime Library type of the OCaml compiler present on your system"]] +opam-root-version: "2.1" +opam-version: "2.0" +repositories: "default" +wrap-build-commands: ["%{hooks}%/sandbox.sh" "build"] {os = "linux" | os = "macos"} +wrap-install-commands: ["%{hooks}%/sandbox.sh" "install"] {os = "linux" | os = "macos"} +wrap-remove-commands: ["%{hooks}%/sandbox.sh" "remove"] {os = "linux" | os = "macos"} +### :: full configred opamrc :: +### rm -rf $OPAMROOT +### +opam-version: "2.0" +repositories: "norepo" {"REPO/"} +default-compiler: "comp" +default-invariant: "comp" { = "1"} +jobs: 9 +download-command: "dl-tool" +download-jobs: 8 +archive-mirrors: "REPO/cache" +solver-criteria: "solver-criteri" +solver-upgrade-criteria: "upgrade-criteri" +solver-fixup-criteria: "fixup-criteri" +solver: "a-solver" +global-variables: [ GLOB "glob" "Set throught opamrc" ] +eval-variables: [ var-to-eval ["true"] "tautology" ] +recommended-tools: [ "recommended" ] +required-tools: [ "required" { "tautology" } ] +init-scripts: +[ "a-script.sh" + """\ +#!/usr/bin/env bash +echo "script $1 launched STOP i repeat STOP script $1 launched" +""" ] +pre-build-commands: ["%{hooks}%/a-script.sh" "pre-build" ] +pre-install-commands: ["%{hooks}%/a-script.sh" "pre-install" ] +pre-remove-commands: ["%{hooks}%/a-script.sh" "pre-remove" ] +pre-session-commands: ["%{hooks}%/a-script.sh" "pre-session" ] +wrap-build-commands: ["%{hooks}%/a-script.sh" "wrap-build" ] +wrap-install-commands: ["%{hooks}%/a-script.sh" "wrap-install" ] +wrap-remove-commands: ["%{hooks}%/a-script.sh" "wrap-remove" ] +post-build-commands: ["%{hooks}%/a-script.sh" "post-build" ] +post-install-commands: ["%{hooks}%/a-script.sh" "post-install" ] +post-remove-commands: ["%{hooks}%/a-script.sh" "post-remove" ] +post-session-commands: ["%{hooks}%/a-script.sh" "post-session" ] +### opam init --bypass-checks --bare --no-setup --config opamrc +Configuring from ${BASEDIR}/opamrc and then from built-in defaults. + +<><> Fetching repository information ><><><><><><><><><><><><><><><><><><><><><> +[norepo] Initialised +### opam-cat $OPAMROOT/config +archive-mirrors: "file://${BASEDIR}/REPO/cache" +default-compiler: ["comp"] +default-invariant: ["comp" {= "1"}] +depext: true +depext-cannot-install: false +depext-run-installs: true +download-command: "dl-tool" +download-jobs: 8 +eval-variables: [var-to-eval ["true"] "tautology"] +global-variables: [GLOB "glob" "Set throught opamrc"] +jobs: 9 +opam-root-version: "2.1" +opam-version: "2.0" +post-build-commands: ["%{hooks}%/a-script.sh" "post-build"] +post-install-commands: ["%{hooks}%/a-script.sh" "post-install"] +post-remove-commands: ["%{hooks}%/a-script.sh" "post-remove"] +post-session-commands: ["%{hooks}%/a-script.sh" "post-session"] +pre-build-commands: ["%{hooks}%/a-script.sh" "pre-build"] +pre-install-commands: ["%{hooks}%/a-script.sh" "pre-install"] +pre-remove-commands: ["%{hooks}%/a-script.sh" "pre-remove"] +pre-session-commands: ["%{hooks}%/a-script.sh" "pre-session"] +repositories: "norepo" +solver: "a-solver" +solver-criteria: "solver-criteri" +solver-fixup-criteria: "fixup-criteri" +solver-upgrade-criteria: "upgrade-criteri" +wrap-build-commands: ["%{hooks}%/a-script.sh" "wrap-build"] +wrap-install-commands: ["%{hooks}%/a-script.sh" "wrap-install"] +wrap-remove-commands: ["%{hooks}%/a-script.sh" "wrap-remove"] +### opam-cat $OPAMROOT/repo/repos-config +opam-version: "2.0" +repositories: "norepo" {"file://${BASEDIR}/REPO"} +### sh $OPAMROOT/opam-init/hooks/a-script.sh test +script test launched STOP i repeat STOP script test launched +### :: partially configured opamrc :: +### rm -rf $OPAMROOT +### +opam-version: "2.0" +repositories: "norepo" {"REPO/"} +default-compiler: "comp" +download-jobs: 8 +archive-mirrors: "REPO/cache" +eval-variables: [ var-to-eval ["true"] "tautology" ] +required-tools: [ "required" { "tautology" } ] +# As fields are overriden, it is needed to recreate sandbox script +init-scripts: [ +[ "a-script.sh" + """\ +#!/usr/bin/env bash +echo "script $1 launched STOP i repeat STOP script $1 launched" +""" ] +[ "sandbox.sh" + """\ +#!/usr/bin/env bash +echo "SUCCESS" +""" ] +] +pre-build-commands: ["%{hooks}%/a-script.sh" "pre-build" ] +wrap-install-commands: ["%{hooks}%/a-script.sh" "wrap-install" ] +post-session-commands: ["%{hooks}%/a-script.sh" "post-session" ] +### opam init --bypass-checks --bare --no-setup --config opamrc +Configuring from ${BASEDIR}/opamrc and then from built-in defaults. + +<><> Fetching repository information ><><><><><><><><><><><><><><><><><><><><><> +[norepo] Initialised +### opam-cat $OPAMROOT/config +archive-mirrors: "file://${BASEDIR}/REPO/cache" +default-compiler: ["comp"] +default-invariant: ["ocaml" {>= "4.05.0"}] +depext: true +depext-cannot-install: false +depext-run-installs: true +download-jobs: 8 +eval-variables: [var-to-eval ["true"] "tautology"] +opam-root-version: "2.1" +opam-version: "2.0" +post-session-commands: ["%{hooks}%/a-script.sh" "post-session"] +pre-build-commands: ["%{hooks}%/a-script.sh" "pre-build"] +repositories: "norepo" +wrap-build-commands: ["%{hooks}%/sandbox.sh" "build"] {os = "linux" | os = "macos"} +wrap-install-commands: ["%{hooks}%/a-script.sh" "wrap-install"] +wrap-remove-commands: ["%{hooks}%/sandbox.sh" "remove"] {os = "linux" | os = "macos"} +### opam-cat $OPAMROOT/repo/repos-config +opam-version: "2.0" +repositories: "norepo" {"file://${BASEDIR}/REPO"} diff --git a/tests/reftests/local-cache.test b/tests/reftests/local-cache.test new file mode 100644 index 00000000000..2aedbb07a92 --- /dev/null +++ b/tests/reftests/local-cache.test @@ -0,0 +1,357 @@ +N0REP0 +### ::: Setup ::: +### +Hi robur! +### tar czf archive.tgz hello +### +Trust me, im' a patch! +### openssl md5 archive.tgz | '.*= ' -> '' >$ ARCHIVE_MD5 +### openssl sha256 archive.tgz | '.*= ' -> '' >$ ARCHIVE_SHA256 +### openssl md5 p.patch | '.*= ' -> '' >$ PATCH_MD5 +### openssl sha256 p.patch | '.*= ' -> '' >$ PATCH_SHA256 +### sh -c "echo '$ARCHIVE_MD5' | cut -c 1-2" >$ PRE_MD5 +### echo "$OPAMROOT/download-cache/md5/$PRE_MD5/$ARCHIVE_MD5" >$ ARCHIVE_MD5_PATH +### sh -c "echo '$ARCHIVE_SHA256' | cut -c 1-2" >$ PRE_SHA256 +### echo "$OPAMROOT/download-cache/sha256/$PRE_SHA256/$ARCHIVE_SHA256" >$ ARCHIVE_SHA256_PATH +### +set -ue +eval "ARCHIVE_MD5_PATH=\"$ARCHIVE_MD5_PATH\"" +eval "ARCHIVE_SHA256_PATH=\"$ARCHIVE_SHA256_PATH\"" + +if command -v cygpath 2> /dev/null > /dev/null ; then + ARCHIVE_MD5_PATH=`cygpath -u "$ARCHIVE_MD5_PATH"` + ARCHIVE_SHA256_PATH=`cygpath -u "$ARCHIVE_SHA256_PATH"` +fi + +check2sum () { + kind=$1 + path=$2 + hsh=`openssl "$kind" "$path" | cut -f 2 -d ' '` + name=`basename "$path"` + if [ "$name" = "$hsh" ]; then + echo "with matching checksum" + else + echo "with mismatching checksum" + fi +} +check () { + path=$1 + if [ -L "$path" ] ; then + out="link," + realpath=`readlink -f "$path"` || true + if [ "$realpath" = "$ARCHIVE_MD5_PATH" ]; then + out="$out to md5 archive" + elif [ "$realpath" = "$ARCHIVE_SHA256_PATH" ]; then + out="$out to sha256 archive" + else + out="$out to unknown path $realpath" + fi + elif [ -f "$path" ] ; then + out="archive," + if echo "$path" | grep -q md5 ; then + out="$out `check2sum md5 $path`" + elif echo "$path" | grep -q sha256 ; then + out="$out `check2sum sha256 $path`" + else + out="$out no checksum validation" + fi + else + out="not found" + fi + echo "$out" +} + +md5=$(check "$ARCHIVE_MD5_PATH") +sha256=$(check "$ARCHIVE_SHA256_PATH") +echo "MD5: $md5" +echo "SHA256: $sha256" +### +set -ue +pkg=$1 +kind=$2 +hsh=$3 +case "$hsh-$kind" in + md5-archive) + HSH=$ARCHIVE_MD5 + break;; + sha256-archive) + HSH=$ARCHIVE_SHA256 + break;; + md5-patch) + HSH=$PATCH_MD5 + break;; + sha256-patch) + HSH=$PATCH_SHA256 + break;; +esac +pkgpath="REPO/packages/${pkg%.*}/$pkg" +sed -i.bak "s/good-$hsh/$HSH/" "$pkgpath/opam" +### +opam-version: "2.0" +maintainer: "nobody" +authors: "nobody neither" +homepage: "https://no.bo.dy" +bug-reports: "https://still.nobo.dy" +dev-repo: "git+https://no.were" +license: "MIT" +synopsis: "Initially empty" +build: [ "test" "-f" "hello" ] +url { + src: "archive.tgz" + checksum: [ + "sha256=good-sha256" + "md5=good-md5" + ] +} +### sh update-hash.sh good-sha256-good-md5.1 archive md5 +### sh update-hash.sh good-sha256-good-md5.1 archive sha256 +### opam update + +<><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><> +[default] synchronised from file://${BASEDIR}/REPO +Now run 'opam upgrade' to apply any package updates. +### opam switch create default --empty +### :I:11: Change archive in cache +### :I:11:a: install with removed md5 frome cache, and kept sha256 +### opam install good-sha256-good-md5 +The following actions will be performed: + - install good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> retrieved good-sha256-good-md5.1 (file://${BASEDIR}/archive.tgz) +-> installed good-sha256-good-md5.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### : rm "$ARCHIVE_MD5_PATH" +### opam remove good-sha256-good-md5 +The following actions will be performed: + - remove good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> removed good-sha256-good-md5.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### opam install good-sha256-good-md5 +The following actions will be performed: + - install good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> retrieved good-sha256-good-md5.1 (cached) +-> installed good-sha256-good-md5.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### :I:11:b: install with removed sha256 frome cache, and kept md5 +### opam clean --download-cache +Clearing cache of downloaded files +### opam reinstall good-sha256-good-md5 +The following actions will be performed: + - recompile good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> retrieved good-sha256-good-md5.1 (file://${BASEDIR}/archive.tgz) +-> removed good-sha256-good-md5.1 +-> installed good-sha256-good-md5.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### rm "$ARCHIVE_SHA256_PATH" +### opam remove good-sha256-good-md5 +The following actions will be performed: + - remove good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> removed good-sha256-good-md5.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: not found +### opam install good-sha256-good-md5 +The following actions will be performed: + - install good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> retrieved good-sha256-good-md5.1 (file://${BASEDIR}/archive.tgz) +-> installed good-sha256-good-md5.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### :I:11:c: corrupt md5 archive in cache +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### opam remove good-sha256-good-md5 +The following actions will be performed: + - remove good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> removed good-sha256-good-md5.1 +Done. +### : rm "$ARCHIVE_MD5_PATH" +### : tar czf "$ARCHIVE_MD5_PATH" p.patch +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### # it's only sha256 that is checked, as it is good, it doesn't check other cache files +### opam install good-sha256-good-md5 +The following actions will be performed: + - install good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> retrieved good-sha256-good-md5.1 (cached) +-> installed good-sha256-good-md5.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### :I:11:d: corrupt sha256 archive in cache +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### opam remove good-sha256-good-md5 +The following actions will be performed: + - remove good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> removed good-sha256-good-md5.1 +Done. +### : cp archive.tgz "$ARCHIVE_MD5_PATH" +### rm "$ARCHIVE_SHA256_PATH" +### tar czf "$ARCHIVE_SHA256_PATH" p.patch +### sh check-cache.sh +MD5: not found +SHA256: archive, with mismatching checksum +### # what happens here is that sha256 is checked first, there is a mismatch on sha256 archive (checking its sha256 & md5), so it is remove, returns file not available, and then it downloads the archive from url +### opam install good-sha256-good-md5 | '[0-9a-z]{32,64}' -> 'hash' +The following actions will be performed: + - install good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +[ERROR] Conflicting file hashes, or broken or compromised cache! + - sha256=hash (MISMATCH) + - md5=hash (MISMATCH) + +-> retrieved good-sha256-good-md5.1 (file://${BASEDIR}/archive.tgz) +-> installed good-sha256-good-md5.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### :I:11:e: Both corrupted +### opam remove good-sha256-good-md5 +The following actions will be performed: + - remove good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> removed good-sha256-good-md5.1 +Done. +### rm "$ARCHIVE_SHA256_PATH" +### tar czf "$ARCHIVE_SHA256_PATH" p.patch +### : rm "$ARCHIVE_MD5_PATH" +### : tar czf "$ARCHIVE_MD5_PATH" p.patch +### sh check-cache.sh +MD5: not found +SHA256: archive, with mismatching checksum +### opam install good-sha256-good-md5 | '[0-9a-z]{32,64}' -> 'hash' +The following actions will be performed: + - install good-sha256-good-md5 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +[ERROR] Conflicting file hashes, or broken or compromised cache! + - sha256=hash (MISMATCH) + - md5=hash (MISMATCH) + +-> retrieved good-sha256-good-md5.1 (file://${BASEDIR}/archive.tgz) +-> installed good-sha256-good-md5.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### +opam-version: "2.0" +maintainer: "nobody" +authors: "nobody neither" +homepage: "https://no.bo.dy" +bug-reports: "https://still.nobo.dy" +dev-repo: "git+https://no.were" +license: "MIT" +synopsis: "Initially empty" +build: [ "test" "-f" "hello" ] +url { + src: "archive.tgz" + checksum: [ + "sha256=good-sha256" + ] +} +### sh update-hash.sh good-sha256.1 archive sha256 +### opam update + +<><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><> +[default] synchronised from file://${BASEDIR}/REPO +Now run 'opam upgrade' to apply any package updates. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### opam install good-sha256.1 +The following actions will be performed: + - install good-sha256 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> retrieved good-sha256.1 (cached) +-> installed good-sha256.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### opam remove good-sha256.1 +The following actions will be performed: + - remove good-sha256 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> removed good-sha256.1 +Done. +### rm "$ARCHIVE_SHA256_PATH" +### opam install good-sha256.1 +The following actions will be performed: + - install good-sha256 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> retrieved good-sha256.1 (file://${BASEDIR}/archive.tgz) +-> installed good-sha256.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum +### opam remove good-sha256.1 +The following actions will be performed: + - remove good-sha256 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> removed good-sha256.1 +Done. +### rm "$ARCHIVE_SHA256_PATH" +### tar czf "$ARCHIVE_SHA256_PATH" p.patch +### sh check-cache.sh +MD5: not found +SHA256: archive, with mismatching checksum +### opam install good-sha256.1 | '[0-9a-z]{32,64}' -> 'hash' +The following actions will be performed: + - install good-sha256 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +[ERROR] Conflicting file hashes, or broken or compromised cache! + - sha256=hash (MISMATCH) + +-> retrieved good-sha256.1 (file://${BASEDIR}/archive.tgz) +-> installed good-sha256.1 +Done. +### sh check-cache.sh +MD5: not found +SHA256: archive, with matching checksum diff --git a/tests/reftests/opamrt-big-upgrade.test b/tests/reftests/opamrt-big-upgrade.test index c61a1790943..56fc1a33e8c 100644 --- a/tests/reftests/opamrt-big-upgrade.test +++ b/tests/reftests/opamrt-big-upgrade.test @@ -88,7 +88,7 @@ installed: [ "yojson.1.1.6" "zed.1.2" ] -### opam switch import init.export --switch test-import --fake +### opam switch import init.export --switch test-import --fake | unordered The following actions will be faked: - install base-unix base - install ocaml-base-compiler 4.01.0beta1 [required by ocaml] diff --git a/tests/reftests/run.ml b/tests/reftests/run.ml index c60ee88bf1a..44a62fa55cc 100644 --- a/tests/reftests/run.ml +++ b/tests/reftests/run.ml @@ -399,7 +399,7 @@ module Parse = struct in let rec get_args_rewr acc = function | [] -> List.rev acc, false, [], None - | "|" :: _ as rewr -> + | ("|"|">$") :: _ as rewr -> let rec get_rewr (unordered, acc) = function | "|" :: re :: "->" :: str :: r -> get_rewr (unordered, (posix_re re, Sed (get_str str)) :: acc) r