diff --git a/master_changes.md b/master_changes.md index a35682daca9..4524a01e7c7 100644 --- a/master_changes.md +++ b/master_changes.md @@ -53,6 +53,7 @@ users) * Compute the list of available depexts on `opam update` [#6489 @arozovyk - fix #6461] * Update depexts availability repository state cache when running `opam update --depexts` [#6489 @arozovyk - fix #6461] * Display status message while loading system package availability during `opam update` [#6489 @arozovyk - fix #6461] + * When loading a repository from a diff, no longer apply updates of unrelated files [#6871 @rjbou - fix 6872] ## Tree @@ -196,6 +197,7 @@ users) * `OpamSolution.get_depexts` remove no longer needed `recover` option that was used with `--depext-only` option [#6489 @arozovyk] ## opam-repository + * `OpamRepositoryPath`: add `extrafile_nv_dir` to retrieve information from a path if it is an extra files path [#6871 @rjbou] ## opam-state * `OpamStateConfig.t`: replace `no_depexts` fields that contains disabling informations by `depexts` field that returns if the depexts mechanism is enabled. This field is automatically update by global config value in `OpamStateConfig.load_defaults` [#6489 @rjbou] @@ -247,3 +249,6 @@ users) * `OpamFilename`: add `is_dir_read_only` [#6489 @rjbou] * `OpamFilename.might_escape`: ensure / is detected as a file separator when called with `~sep:Unspecified` on Windows [#6897 @kit-ty-kate] * `OpamFilename.Unix` was added abstracting over `/` separated paths regardless of the current system [#6914 @rjbou @kit-ty-kate] + * `OpamFilename`: add `to_list` that deconstructs a `filename` path [#6871 @rjbou] + * `OpamFilename.Dir`: add `of_list` that constructs a `dirname` from a string path elements [#6871 @rjbou] + * `OpamFilename.Unix`: add `starts_with`, `basename`, `dirname` [#6871 @rjbou] diff --git a/src/core/opamFilename.ml b/src/core/opamFilename.ml index e97de1df57b..3b553cf4021 100644 --- a/src/core/opamFilename.ml +++ b/src/core/opamFilename.ml @@ -59,6 +59,8 @@ module Dir = struct OpamSystem.real_path (OpamSystem.forward_to_back dirname) let to_string dirname = dirname + let of_list dirs = + String.concat Filename.dir_sep dirs end @@ -813,4 +815,16 @@ module Unix = struct let of_filename x = OpamSystem.back_to_forward (concat x.dirname x.basename) let to_filename x = {dirname = dirname x; basename = basename x} + + let to_list (t:t) = + let base d = Base.to_string (basename_dir d) in + let rec aux acc dir = + let d = dirname_dir dir in + if d <> dir then aux (base dir :: acc) d + else base dir :: acc in + aux [] t + + let starts_with prefix filename = + OpamCompat.String.starts_with ~prefix filename + end diff --git a/src/core/opamFilename.mli b/src/core/opamFilename.mli index c20cafc3edc..992b3232e02 100644 --- a/src/core/opamFilename.mli +++ b/src/core/opamFilename.mli @@ -27,7 +27,11 @@ module Base: sig end (** Directory names *) -module Dir: OpamStd.ABSTRACT +module Dir: sig + include OpamStd.ABSTRACT + + val of_list: string list -> t +end (** Return the current working directory *) val cwd: unit -> Dir.t @@ -426,4 +430,17 @@ module Unix : sig val of_filename : filename -> t val to_filename : t -> filename + + (** Check whether a filename starts by a given Dir.t *) + val starts_with: Dir.t -> t -> bool + + (** Return the base name *) + val basename: t -> Base.t + + (** Return the directory name *) + val dirname: t -> Dir.t + + (** Deconstruct a filename into a list of path elements *) + val to_list: t -> string list + end diff --git a/src/repository/opamRepositoryPath.ml b/src/repository/opamRepositoryPath.ml index ccc79df1bbb..98e2d2cd9d6 100644 --- a/src/repository/opamRepositoryPath.ml +++ b/src/repository/opamRepositoryPath.ml @@ -53,6 +53,35 @@ let url repo_root prefix nv = let files repo_root prefix nv = packages repo_root prefix nv / "files" +let extrafile_nv_dir filename = + let rec find_files prefix_files tail = + match tail with + | "files"::_ -> Some prefix_files + | h::t -> find_files (h::prefix_files) t + | [] -> None + in + let rec aux (pre, rest) = + match rest with + | "packages"::packages -> + (* We don't check packages/name/name.version layer because repo loading + is more permissive *) + (match find_files [] packages with + | Some (nv::prefix_files) -> + (match OpamPackage.of_string_opt nv with + | Some pkg -> + let dir = + List.rev (nv :: prefix_files @ ["packages"]) + |> OpamFilename.Dir.of_list + |> OpamFilename.Unix.Dir.of_dir + in + Some (pkg, dir) + | None -> None) + | None | Some [] -> None) + | p::r -> aux (p::pre, r) + | [] -> None + in + aux ([], OpamFilename.Unix.to_list filename) + module Remote = struct (** URL, not FS paths *) open OpamUrl.Op diff --git a/src/repository/opamRepositoryPath.mli b/src/repository/opamRepositoryPath.mli index 19a8a576390..6e3110d30d6 100644 --- a/src/repository/opamRepositoryPath.mli +++ b/src/repository/opamRepositoryPath.mli @@ -51,6 +51,11 @@ val url: dirname -> string option -> package -> OpamFile.URL_legacy.t OpamFile.t (** files {i $repo/packages/XXX/$NAME.$VERSION/files} *) val files: dirname -> string option -> package -> dirname +(** Returns package and main directory if the path is an extrafile one from + a repository root: {i packages/[/...]/$NAME.$VERSION/files/...} +*) +val extrafile_nv_dir: unix_filename -> (package * unix_dirname) option + (** Url constructor for parts of remote repositories, when applicable (http and rsync). Function take the repo's root url. *) module Remote: sig diff --git a/src/state/opamRepositoryState.ml b/src/state/opamRepositoryState.ml index eff38dff0fc..7fa73f2cd2f 100644 --- a/src/state/opamRepositoryState.ml +++ b/src/state/opamRepositoryState.ml @@ -141,76 +141,108 @@ let load_opams_from_dir repo_name repo_root = let load_opams_from_diff repo diffs rt = if OpamConsole.disp_status_line () || OpamConsole.verbose () then OpamConsole.status_line "Processing: [%s: loading data]" - (OpamConsole.colorise `blue (OpamRepositoryName.to_string repo.repo_name)); - let existing_opams = - OpamRepositoryName.Map.find repo.repo_name rt.repo_opams - in + (OpamConsole.colorise `blue + (OpamRepositoryName.to_string repo.repo_name)); let repo_root = get_repo_root rt repo in - (* processed_dirs: used to avoid re-read in case of diff generated by extra files. - added_pkgs: used to skip removing version-equivalent packages *) - let process_file (opams, processed_dirs, added_pkgs) file ~is_removal = - let pkg_dir = - let file = OpamFilename.raw file in - let dirname = OpamFilename.dirname file in - let basename = OpamFilename.basename_dir dirname in - let full_path = - Filename.concat - (OpamFilename.Dir.to_string repo_root) - (OpamFilename.Dir.to_string dirname) + let open OpamFilename.Op in + let additions, removals, xfiles = + let add, remove = + let packages_dir = + "packages" + |> OpamFilename.Unix.Dir.of_string in - if OpamFilename.Base.to_string basename = "files" then - OpamFilename.Dir.of_string (Filename.dirname full_path) - else - OpamFilename.Dir.of_string full_path + let is_opam_file filename = + if OpamFilename.Unix.starts_with packages_dir filename then + if OpamFilename.Unix.Base.equal (OpamFilename.Unix.basename filename) + (OpamFilename.Unix.Base.of_string "opam") then + match OpamPackage.of_filename (OpamFilename.Unix.to_filename filename) with + | Some nv -> Some nv + | None -> + log "ERR: directory name not a valid package: ignored %s" + (OpamFilename.to_string + (repo_root // (OpamFilename.Unix.to_string filename))); + None + else None + else None + in + let xfile_info = OpamRepositoryPath.extrafile_nv_dir in + let aux file ~rm (adds, rms, xfs) = + let file = OpamFilename.Unix.of_string file in + match is_opam_file file with + | Some nv -> + if rm then + adds, OpamPackage.Set.add nv rms, xfs + else + OpamPackage.Map.add nv file adds, rms, xfs + | None -> + match xfile_info file with + | Some (nv, dir) -> + (* TAR TODO : opam repo path install nv dir should return tarfile *) + adds, rms, OpamPackage.Map.add nv dir xfs + | None -> adds, rms, xfs + in + aux ~rm:false, aux ~rm:true in - if OpamFilename.Dir.Set.mem pkg_dir processed_dirs then - opams, processed_dirs, added_pkgs - else - let processed_dirs = OpamFilename.Dir.Set.add pkg_dir processed_dirs in - match read_package_opam ~repo_name:repo.repo_name ~repo_root pkg_dir with - | Some (nv, opam) -> - let added_pkgs = OpamPackage.Set.add nv added_pkgs in - OpamPackage.Map.add nv opam opams, processed_dirs, added_pkgs - | None -> - if is_removal then - match OpamPackage.of_dirname pkg_dir with - | None -> - log "ERR: directory name not a valid package: ignored %s" - (OpamFilename.Dir.to_string pkg_dir); - opams, processed_dirs, added_pkgs - | Some nv -> - if OpamPackage.Set.mem nv added_pkgs then - opams, processed_dirs, added_pkgs - else - OpamPackage.Map.remove nv opams, processed_dirs, added_pkgs + let operations acc = function + | Patch.Edit (old_file, new_file) -> + if String.equal old_file new_file then + add new_file acc else - opams, processed_dirs, added_pkgs + add new_file acc |> remove old_file + | Patch.Delete file -> remove file acc + | Patch.Create file -> add file acc + | Patch.Git_ext (file1, file2, git_ext) -> + match git_ext with + | Patch.Rename_only (_, _) -> + add file2 acc |> remove file1 + | Patch.Delete_only -> remove file1 acc + | Patch.Create_only -> add file2 acc + in + List.fold_left operations OpamPackage.(Map.empty, Set.empty, Map.empty) diffs in - let remove_file file acc = process_file acc file ~is_removal:true in - let add_file file acc = process_file acc file ~is_removal:false in - let process_operation acc = function - | Patch.Edit (old_file, new_file) -> - if String.equal old_file new_file - then - add_file new_file acc - else - remove_file old_file acc |> add_file new_file - | Patch.Delete file -> remove_file file acc - | Patch.Create file -> add_file file acc - | Patch.Git_ext (file1, file2, git_ext) -> - match git_ext with - | Patch.Rename_only (_, _) -> remove_file file1 acc |> add_file file2 - | Patch.Delete_only -> remove_file file1 acc - | Patch.Create_only -> add_file file2 acc + let xfiles = + OpamPackage.Map.fold (fun nv dir lst -> + if OpamPackage.Map.mem nv additions + || OpamPackage.Set.mem nv removals then lst + else dir::lst) + xfiles [] in - Fun.protect - (fun () -> - let opams, _, _ = - List.fold_left process_operation - (existing_opams, OpamFilename.Dir.Set.empty, OpamPackage.Set.empty) - diffs - in - opams) + let read_and_add = + let read_package_opam dir = + let dir = OpamFilename.Unix.Dir.to_dir dir in + let dir = repo_root / OpamFilename.Dir.to_string dir in + read_package_opam ~repo_name:repo.repo_name ~repo_root dir + in + fun dir opams -> + match read_package_opam dir with + | Some (nv, opam) -> OpamPackage.Map.add nv opam opams + | None -> + log "ERR: Could not load %s, ignored" + (OpamFilename.Unix.to_string OpamFilename.Unix.Op.(dir//"opam")); + opams + in + let process_operations opams = + (* remove obsolete packages *) + let opams = + OpamPackage.Set.fold OpamPackage.Map.remove removals opams + in + (* add new packages *) + let opams = + OpamPackage.Map.fold (fun _nv file -> + read_and_add (OpamFilename.Unix.dirname file)) + additions opams + in + (* update extra files *) + let opams = + List.fold_left (fun opams dir -> read_and_add dir opams) + opams xfiles + in + opams + in + let existing_opams = + OpamRepositoryName.Map.find repo.repo_name rt.repo_opams + in + Fun.protect (fun () -> process_operations existing_opams) ~finally:OpamConsole.clear_status let load_repo repo repo_root = diff --git a/tests/reftests/dune.inc b/tests/reftests/dune.inc index 2033956de02..6374d6dd796 100644 --- a/tests/reftests/dune.inc +++ b/tests/reftests/dune.inc @@ -1868,6 +1868,27 @@ %{targets} (run ./run.exe %{exe:../../src/client/opamMain.exe.exe} %{dep:remove.test} %{read-lines:testing-env})))) +(rule + (alias reftest-repository-formats) + (enabled_if (and (or (<> %{env:TESTALL=1} 0) (= %{env:TESTN0REP0=0} 1)))) + (action + (diff repository-formats.test repository-formats.out))) + +(alias + (name reftest) + (enabled_if (and (or (<> %{env:TESTALL=1} 0) (= %{env:TESTN0REP0=0} 1)))) + (deps (alias reftest-repository-formats))) + +(rule + (targets repository-formats.out) + (deps root-N0REP0) + (enabled_if (and (or (<> %{env:TESTALL=1} 0) (= %{env:TESTN0REP0=0} 1)))) + (package opam) + (action + (with-stdout-to + %{targets} + (run ./run.exe %{exe:../../src/client/opamMain.exe.exe} %{dep:repository-formats.test} %{read-lines:testing-env})))) + (rule (alias reftest-repository-patchdiff) (enabled_if (and (or (<> %{env:TESTALL=1} 0) (= %{env:TESTN0REP0=0} 1)))) diff --git a/tests/reftests/extrafile.test b/tests/reftests/extrafile.test index 7114bcfee35..ebce9f21b68 100644 --- a/tests/reftests/extrafile.test +++ b/tests/reftests/extrafile.test @@ -695,7 +695,6 @@ cp p.patch $pkgpath/files/dir/ <><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><> [default] synchronised from file://${BASEDIR}/REPO -opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default/packages/good-md5-good-sha256/good-md5-good-sha256.1: missing from 'files' directory (1) Now run 'opam upgrade' to apply any package updates. ### opam install good-nested-md5.1 The following actions will be performed: diff --git a/tests/reftests/repository-formats.test b/tests/reftests/repository-formats.test new file mode 100644 index 00000000000..82ce55e2910 --- /dev/null +++ b/tests/reftests/repository-formats.test @@ -0,0 +1,580 @@ +N0REP0 +### opam repository add default-strict ./REPO +[WARNING] No switch is currently set, perhaps you meant '--set-default'? +[default-strict] Initialised +[ERROR] No switch is currently set. Please use 'opam switch' to set or install a switch +# Return code 50 # +### +I'm the root one +### +I'm the second one, in a directory +### openssl md5 fst | '.*= ' -> '' >$ FST_MD5 +### openssl md5 snd | '.*= ' -> '' >$ SND_MD5 +### +set -eu +path="REPO/$1" +files="$path/files" +under="un/der" +innerfiles="$files/$under" +mkdir -p "$innerfiles" +cp fst "$files/" +cp snd "$innerfiles/" +cat > "$path/opam" << EOF +opam-version: "2.0" +extra-files: [ + ["fst" "md5=$FST_MD5"] + ["$under/snd" "md5=$SND_MD5"] +] +build: [ + [ "test" "-f" "fst" ] + [ "test" "-f" "$under/snd" ] +] +EOF +### +set -ue +n="$1" +path="REPO/$2" +cat >> "$path/opam" << EOF +name: "$n" +version: "1" +EOF +### sh populate.sh packages/good/good.1 +### sh populate.sh packages/not/no-n-nv.1 +### sh populate.sh packages/ba/baz/n-nv-not-root.1 +### sh populate.sh packages/v/e/r/y/very-inner.1 +### sh populate.sh packages/i/n/e/r/very-inned-n-nv/very-inner-n-nv.1 +### sh populate.sh packages/direct-root.1 +### sh populate.sh packages/no-nv +### sh add-nv.sh no-nv packages/no-nv +### sh populate.sh root-no-nv +### sh add-nv.sh root-no-nv root-no-nv +### sh populate.sh packages/not-same-nv-in/not-same-nv-in.2 +### sh add-nv.sh different packages/not-same-nv-in/not-same-nv-in.2 +### sh populate.sh pkg/z-good/z-good.1 +### sh populate.sh pkg/z-not/z-no-n-nv.1 +### sh populate.sh pkg/z-ba/z-baz/z-n-nv-not-root.1 +### sh populate.sh pkg/z-v/z-e/z-r/z-y/z-very-inner.1 +### sh populate.sh pkg/z-i/z-n/z-e/z-r/z-very-inned-n-nv/z-very-inner-n-nv.1 +### sh populate.sh pkg/z-direct-root.1 +### sh populate.sh pkg/z-no-nv +### OPAMYES=1 OPAMSTRICT=0 +### opam sw cr --empty exotic-formats-update +### :I: update from dir (diff mode) +### OPAMDEBUGSECTIONS="FILE(opam) opam-file RSTATE UPDATE" OPAMDEBUG=-3 opam update default-strict --strict +FILE(config) Read ${BASEDIR}/OPAM/config in 0.000s +RSTATE LOAD-REPOSITORY-STATE @ ${BASEDIR}/OPAM +RSTATE Cache found + +<><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><> +[default-strict] synchronised from file://${BASEDIR}/REPO +UPDATE Repository has new changes +RSTATE ERR: directory name not a valid package: ignored ${BASEDIR}/OPAM/repo/default-strict/packages/no-nv/opam +FILE(opam) Read ${BASEDIR}/OPAM/repo/default-strict/packages/direct-root.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default-strict/packages/good/good.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default-strict/packages/ba/baz/n-nv-not-root.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default-strict/packages/not/no-n-nv.1/opam in 0.000s +[ERROR] In ${BASEDIR}/OPAM/repo/default-strict/packages/not-same-nv-in/not-same-nv-in.2/opam: + This file is for package 'not-same-nv-in.2' but has mismatching fields 'name:different 'version:1. +[ERROR] Strict mode: aborting +[ERROR] Could not update repository "default-strict": OpamStd.OpamSys.Exit(30) +# Return code 40 # +### OPAMDEBUGSECTIONS="FILE(opam) opam-file RSTATE UPDATE" OPAMDEBUG=-3 opam update default +FILE(config) Read ${BASEDIR}/OPAM/config in 0.000s +RSTATE LOAD-REPOSITORY-STATE @ ${BASEDIR}/OPAM +RSTATE Cache found + +<><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><> +[default] synchronised from file://${BASEDIR}/REPO +UPDATE Repository has new changes +RSTATE ERR: directory name not a valid package: ignored ${BASEDIR}/OPAM/repo/default/packages/no-nv/opam +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/direct-root.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/good/good.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/ba/baz/n-nv-not-root.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/not/no-n-nv.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/not-same-nv-in/not-same-nv-in.2/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/v/e/r/y/very-inner.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/i/n/e/r/very-inned-n-nv/very-inner-n-nv.1/opam in 0.000s +Now run 'opam upgrade' to apply any package updates. +### : list all +### opam list -A +# Packages matching: any +# Name # Installed # Synopsis +direct-root -- +good -- +n-nv-not-root -- +no-n-nv -- +not-same-nv-in -- +very-inner -- +very-inner-n-nv -- +### : install all +### opam install good.1 +The following actions will be performed: +=== install 1 package + - install good 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed good.1 +Done. +### opam install no-n-nv.1 +The following actions will be performed: +=== install 1 package + - install no-n-nv 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed no-n-nv.1 +Done. +### opam install n-nv-not-root.1 +The following actions will be performed: +=== install 1 package + - install n-nv-not-root 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed n-nv-not-root.1 +Done. +### opam install very-inner.1 +The following actions will be performed: +=== install 1 package + - install very-inner 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed very-inner.1 +Done. +### opam install very-inner-n-nv.1 +The following actions will be performed: +=== install 1 package + - install very-inner-n-nv 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed very-inner-n-nv.1 +Done. +### opam install direct-root.1 +The following actions will be performed: +=== install 1 package + - install direct-root 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed direct-root.1 +Done. +### opam install no-nv +[ERROR] No package named no-nv found. +# Return code 5 # +### opam install root-no-nv +[ERROR] No package named root-no-nv found. +# Return code 5 # +### opam install not-same-nv-in.2 +The following actions will be performed: +=== install 1 package + - install not-same-nv-in 2 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed not-same-nv-in.2 +Done. +### opam install z-good.1 +[ERROR] No package named z-good found. +# Return code 5 # +### opam install z-no-n-nv.1 +[ERROR] No package named z-no-n-nv found. +# Return code 5 # +### opam install z-n-nv-not-root.1 +[ERROR] No package named z-n-nv-not-root found. +# Return code 5 # +### opam install z-very-inner.1 +[ERROR] No package named z-very-inner found. +# Return code 5 # +### opam install z-very-inner-n-nv.1 +[ERROR] No package named z-very-inner-n-nv found. +# Return code 5 # +### opam install z-direct-root.1 +[ERROR] No package named z-direct-root found. +# Return code 5 # +### opam install z-no-nv +[ERROR] No package named z-no-nv found. +# Return code 5 # +### :II: update from void (dir mode) +### opam sw cr --empty exotic-formats-from-scratch +### OPAMDEBUGSECTIONS="FILE(opam) opam-file RSTATE UPDATE" OPAMDEBUG=-3 opam repository add new-default-strict ./REPO --this-switch --strict +FILE(config) Read ${BASEDIR}/OPAM/config in 0.000s +RSTATE LOAD-REPOSITORY-STATE @ ${BASEDIR}/OPAM +RSTATE Cache found +[new-default-strict] Initialised +UPDATE Repository has new changes +[ERROR] In ${BASEDIR}/OPAM/repo/new-default-strict/packages/not-same-nv-in/not-same-nv-in.2/opam: + This file is for package 'not-same-nv-in.2' but has mismatching fields 'name:different 'version:1. +[ERROR] Strict mode: aborting +[ERROR] Could not update repository "new-default-strict": OpamStd.OpamSys.Exit(30) +[ERROR] Initial repository fetch failed +# Return code 40 # +### OPAMDEBUGSECTIONS="FILE(opam) opam-file RSTATE UPDATE" OPAMDEBUG=-3 opam repository add new-default ./REPO --this-switch | unordered +FILE(config) Read ${BASEDIR}/OPAM/config in 0.000s +RSTATE LOAD-REPOSITORY-STATE @ ${BASEDIR}/OPAM +RSTATE Cache found +[new-default] Initialised +UPDATE Repository has new changes +FILE(opam) Read ${BASEDIR}/OPAM/repo/new-default/packages/not-same-nv-in/not-same-nv-in.2/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/new-default/packages/no-nv/opam in 0.000s +RSTATE ERR: directory name not a valid package: ignored ${BASEDIR}/OPAM/repo/new-default/packages/no-nv/opam +FILE(opam) Read ${BASEDIR}/OPAM/repo/new-default/packages/direct-root.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/new-default/packages/i/n/e/r/very-inned-n-nv/very-inner-n-nv.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/new-default/packages/v/e/r/y/very-inner.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/new-default/packages/ba/baz/n-nv-not-root.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/new-default/packages/not/no-n-nv.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/new-default/packages/good/good.1/opam in 0.000s +### : list all +### opam list -A +# Packages matching: any +# Name # Installed # Synopsis +direct-root -- +good -- +n-nv-not-root -- +no-n-nv -- +not-same-nv-in -- +very-inner -- +very-inner-n-nv -- +### : install all +### opam install good.1 +The following actions will be performed: +=== install 1 package + - install good 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed good.1 +Done. +### opam install no-n-nv.1 +The following actions will be performed: +=== install 1 package + - install no-n-nv 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed no-n-nv.1 +Done. +### opam install n-nv-not-root.1 +The following actions will be performed: +=== install 1 package + - install n-nv-not-root 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed n-nv-not-root.1 +Done. +### opam install very-inner.1 +The following actions will be performed: +=== install 1 package + - install very-inner 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed very-inner.1 +Done. +### opam install very-inner-n-nv.1 +The following actions will be performed: +=== install 1 package + - install very-inner-n-nv 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed very-inner-n-nv.1 +Done. +### opam install direct-root.1 +The following actions will be performed: +=== install 1 package + - install direct-root 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed direct-root.1 +Done. +### opam install no-nv +[ERROR] No package named no-nv found. +# Return code 5 # +### opam install root-no-nv +[ERROR] No package named root-no-nv found. +# Return code 5 # +### opam install not-same-nv-in.2 +The following actions will be performed: +=== install 1 package + - install not-same-nv-in 2 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed not-same-nv-in.2 +Done. +### opam install not-same-nv-in.2 +[NOTE] Package not-same-nv-in is already installed (current version is 2). +### opam install z-good.1 +[ERROR] No package named z-good found. +# Return code 5 # +### opam install z-no-n-nv.1 +[ERROR] No package named z-no-n-nv found. +# Return code 5 # +### opam install z-n-nv-not-root.1 +[ERROR] No package named z-n-nv-not-root found. +# Return code 5 # +### opam install z-very-inner.1 +[ERROR] No package named z-very-inner found. +# Return code 5 # +### opam install z-very-inner-n-nv.1 +[ERROR] No package named z-very-inner-n-nv found. +# Return code 5 # +### opam install z-direct-root.1 +[ERROR] No package named z-direct-root found. +# Return code 5 # +### opam install z-no-nv +[ERROR] No package named z-no-nv found. +# Return code 5 # +### :III: Update only extra-files +### +yet another file, no longer ignored! +### openssl md5 thrd | '.*= ' -> '' >$ THRD_MD5 +### :III::1: first add in opam file +### +set -eu +path="REPO/$1" +files="$path/files" +under="un/der" +innerfiles="$files/$under" +cat > "$path/opam" << EOF +opam-version: "2.0" +extra-files: [ + ["fst" "md5=$FST_MD5"] + ["$under/snd" "md5=$SND_MD5"] + ["$under/thrd" "md5=$THRD_MD5"] +] +build: [ + [ "test" "-f" "fst" ] + [ "test" "-f" "$under/snd" ] + [ "test" "-f" "$under/thrd" ] +] +EOF +### sh xfile-opam.sh packages/good/good.1 +### sh xfile-opam.sh packages/not/no-n-nv.1 +### sh xfile-opam.sh packages/ba/baz/n-nv-not-root.1 +### sh xfile-opam.sh packages/v/e/r/y/very-inner.1 +### sh xfile-opam.sh packages/i/n/e/r/very-inned-n-nv/very-inner-n-nv.1 +### sh xfile-opam.sh packages/direct-root.1 +### sh xfile-opam.sh packages/no-nv +### sh add-nv.sh no-nv packages/no-nv +### sh xfile-opam.sh root-no-nv +### sh add-nv.sh root-no-nv root-no-nv +### sh xfile-opam.sh packages/not-same-nv-in/not-same-nv-in.2 +### sh add-nv.sh different packages/not-same-nv-in/not-same-nv-in.2 +### sh xfile-opam.sh pkg/z-good/z-good.1 +### sh xfile-opam.sh pkg/z-not/z-no-n-nv.1 +### sh xfile-opam.sh pkg/z-ba/z-baz/z-n-nv-not-root.1 +### sh xfile-opam.sh pkg/z-v/z-e/z-r/z-y/z-very-inner.1 +### sh xfile-opam.sh pkg/z-i/z-n/z-e/z-r/z-very-inned-n-nv/z-very-inner-n-nv.1 +### sh xfile-opam.sh pkg/z-direct-root.1 +### sh xfile-opam.sh pkg/z-no-nv +### OPAMDEBUGSECTIONS="FILE(opam) opam-file RSTATE UPDATE" OPAMDEBUG=-3 opam update default-strict --strict | unordered +FILE(config) Read ${BASEDIR}/OPAM/config in 0.000s +RSTATE LOAD-REPOSITORY-STATE @ ${BASEDIR}/OPAM +RSTATE Cache found + +<><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><> +[default-strict] synchronised from file://${BASEDIR}/REPO +UPDATE Repository has new changes +RSTATE ERR: directory name not a valid package: ignored ${BASEDIR}/OPAM/repo/default-strict/packages/no-nv/opam +FILE(opam) Read ${BASEDIR}/OPAM/repo/default-strict/packages/direct-root.1/opam in 0.000s +opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default-strict/packages/direct-root.1: missing from 'files' directory (1) +FILE(opam) Read ${BASEDIR}/OPAM/repo/default-strict/packages/good/good.1/opam in 0.000s +opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default-strict/packages/good/good.1: missing from 'files' directory (1) +FILE(opam) Read ${BASEDIR}/OPAM/repo/default-strict/packages/ba/baz/n-nv-not-root.1/opam in 0.000s +opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default-strict/packages/ba/baz/n-nv-not-root.1: missing from 'files' directory (1) +FILE(opam) Read ${BASEDIR}/OPAM/repo/default-strict/packages/not/no-n-nv.1/opam in 0.000s +opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default-strict/packages/not/no-n-nv.1: missing from 'files' directory (1) +[ERROR] In ${BASEDIR}/OPAM/repo/default-strict/packages/not-same-nv-in/not-same-nv-in.2/opam: + This file is for package 'not-same-nv-in.2' but has mismatching fields 'name:different 'version:1. +[ERROR] Strict mode: aborting +[ERROR] Could not update repository "default-strict": OpamStd.OpamSys.Exit(30) +# Return code 40 # +### OPAMDEBUGSECTIONS="FILE(opam) opam-file RSTATE UPDATE" OPAMDEBUG=-3 opam update default +FILE(config) Read ${BASEDIR}/OPAM/config in 0.000s +RSTATE LOAD-REPOSITORY-STATE @ ${BASEDIR}/OPAM +RSTATE Cache found + +<><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><> +[default] synchronised from file://${BASEDIR}/REPO +UPDATE Repository has new changes +RSTATE ERR: directory name not a valid package: ignored ${BASEDIR}/OPAM/repo/default/packages/no-nv/opam +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/direct-root.1/opam in 0.000s +opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default/packages/direct-root.1: missing from 'files' directory (1) +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/good/good.1/opam in 0.000s +opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default/packages/good/good.1: missing from 'files' directory (1) +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/ba/baz/n-nv-not-root.1/opam in 0.000s +opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default/packages/ba/baz/n-nv-not-root.1: missing from 'files' directory (1) +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/not/no-n-nv.1/opam in 0.000s +opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default/packages/not/no-n-nv.1: missing from 'files' directory (1) +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/not-same-nv-in/not-same-nv-in.2/opam in 0.000s +opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default/packages/not-same-nv-in/not-same-nv-in.2: missing from 'files' directory (1) +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/v/e/r/y/very-inner.1/opam in 0.000s +opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default/packages/v/e/r/y/very-inner.1: missing from 'files' directory (1) +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/i/n/e/r/very-inned-n-nv/very-inner-n-nv.1/opam in 0.000s +opam-file Mismatching extra-files at ${BASEDIR}/OPAM/repo/default/packages/i/n/e/r/very-inned-n-nv/very-inner-n-nv.1: missing from 'files' directory (1) +Now run 'opam upgrade' to apply any package updates. +### :III::2: then add the extrafiles +### +set -eu +path="REPO/$1" +files="$path/files" +under="un/der" +innerfiles="$files/$under" +cp thrd "$innerfiles/" +### sh xfile.sh packages/good/good.1 +### sh xfile.sh packages/not/no-n-nv.1 +### sh xfile.sh packages/ba/baz/n-nv-not-root.1 +### sh xfile.sh packages/v/e/r/y/very-inner.1 +### sh xfile.sh packages/i/n/e/r/very-inned-n-nv/very-inner-n-nv.1 +### sh xfile.sh packages/direct-root.1 +### sh xfile.sh packages/no-nv +### sh xfile.sh root-no-nv +### sh xfile.sh packages/not-same-nv-in/not-same-nv-in.2 +### sh xfile.sh pkg/z-good/z-good.1 +### sh xfile.sh pkg/z-not/z-no-n-nv.1 +### sh xfile.sh pkg/z-ba/z-baz/z-n-nv-not-root.1 +### sh xfile.sh pkg/z-v/z-e/z-r/z-y/z-very-inner.1 +### sh xfile.sh pkg/z-i/z-n/z-e/z-r/z-very-inned-n-nv/z-very-inner-n-nv.1 +### sh xfile.sh pkg/z-direct-root.1 +### sh xfile.sh pkg/z-no-nv +### OPAMDEBUGSECTIONS="FILE(opam) opam-file RSTATE UPDATE" OPAMDEBUG=-3 opam update default-strict --strict | unordered +FILE(config) Read ${BASEDIR}/OPAM/config in 0.000s +RSTATE LOAD-REPOSITORY-STATE @ ${BASEDIR}/OPAM +RSTATE Cache found + +<><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><> +[default-strict] synchronised from file://${BASEDIR}/REPO +UPDATE Repository has new changes +FILE(opam) Read ${BASEDIR}/OPAM/repo/default-strict/packages/i/n/e/r/very-inned-n-nv/very-inner-n-nv.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default-strict/packages/v/e/r/y/very-inner.1/opam in 0.000s +[ERROR] In ${BASEDIR}/OPAM/repo/default-strict/packages/not-same-nv-in/not-same-nv-in.2/opam: + This file is for package 'not-same-nv-in.2' but has mismatching fields 'name:different 'version:1. +[ERROR] Strict mode: aborting +[ERROR] Could not update repository "default-strict": OpamStd.OpamSys.Exit(30) +# Return code 40 # +### OPAMDEBUGSECTIONS="FILE(opam) opam-file RSTATE UPDATE" OPAMDEBUG=-3 opam update default | unordered +FILE(config) Read ${BASEDIR}/OPAM/config in 0.000s +RSTATE LOAD-REPOSITORY-STATE @ ${BASEDIR}/OPAM +RSTATE Cache found + +<><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><> +[default] synchronised from file://${BASEDIR}/REPO +UPDATE Repository has new changes +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/i/n/e/r/very-inned-n-nv/very-inner-n-nv.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/v/e/r/y/very-inner.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/not-same-nv-in/not-same-nv-in.2/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/not/no-n-nv.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/ba/baz/n-nv-not-root.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/good/good.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/OPAM/repo/default/packages/direct-root.1/opam in 0.000s +### :III:3: list all +### opam switch create xfiles --empty +### opam list -A +# Packages matching: any +# Name # Installed # Synopsis +direct-root -- +good -- +n-nv-not-root -- +no-n-nv -- +not-same-nv-in -- +very-inner -- +very-inner-n-nv -- +### :III:4: install all +### opam install good.1 +The following actions will be performed: +=== install 1 package + - install good 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed good.1 +Done. +### opam install no-n-nv.1 +The following actions will be performed: +=== install 1 package + - install no-n-nv 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed no-n-nv.1 +Done. +### opam install n-nv-not-root.1 +The following actions will be performed: +=== install 1 package + - install n-nv-not-root 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed n-nv-not-root.1 +Done. +### opam install very-inner.1 +The following actions will be performed: +=== install 1 package + - install very-inner 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed very-inner.1 +Done. +### opam install very-inner-n-nv.1 +The following actions will be performed: +=== install 1 package + - install very-inner-n-nv 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed very-inner-n-nv.1 +Done. +### opam install direct-root.1 +The following actions will be performed: +=== install 1 package + - install direct-root 1 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed direct-root.1 +Done. +### opam install no-nv +[ERROR] No package named no-nv found. +# Return code 5 # +### opam install root-no-nv +[ERROR] No package named root-no-nv found. +# Return code 5 # +### opam install not-same-nv-in.2 +The following actions will be performed: +=== install 1 package + - install not-same-nv-in 2 + +<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> +-> installed not-same-nv-in.2 +Done. +### opam install z-good.1 +[ERROR] No package named z-good found. +# Return code 5 # +### opam install z-no-n-nv.1 +[ERROR] No package named z-no-n-nv found. +# Return code 5 # +### opam install z-n-nv-not-root.1 +[ERROR] No package named z-n-nv-not-root found. +# Return code 5 # +### opam install z-very-inner.1 +[ERROR] No package named z-very-inner found. +# Return code 5 # +### opam install z-very-inner-n-nv.1 +[ERROR] No package named z-very-inner-n-nv found. +# Return code 5 # +### opam install z-direct-root.1 +[ERROR] No package named z-direct-root found. +# Return code 5 # +### opam install z-no-nv +[ERROR] No package named z-no-nv found. +# Return code 5 # +### :X: opam admin +### mv REPO REPO.bak +### sh -c "mv REPO.bak/* ." +### OPAMDEBUGSECTIONS="FILE(opam) opam-file RSTATE" OPAMDEBUG=-3 opam admin list | unordered +FILE(config) Read ${BASEDIR}/OPAM/config in 0.000s +FILE(opam) Read ${BASEDIR}/packages/not-same-nv-in/not-same-nv-in.2/opam in 0.000s +FILE(opam) Read ${BASEDIR}/packages/no-nv/opam in 0.000s +RSTATE ERR: directory name not a valid package: ignored ${BASEDIR}/packages/no-nv/opam +FILE(opam) Read ${BASEDIR}/packages/direct-root.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/packages/i/n/e/r/very-inned-n-nv/very-inner-n-nv.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/packages/v/e/r/y/very-inner.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/packages/ba/baz/n-nv-not-root.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/packages/not/no-n-nv.1/opam in 0.000s +FILE(opam) Read ${BASEDIR}/packages/good/good.1/opam in 0.000s +# Packages matching: available +# Name # Installed # Synopsis +direct-root -- +good -- +n-nv-not-root -- +no-n-nv -- +not-same-nv-in -- +very-inner -- +very-inner-n-nv --