Hannes Mehnert
f4da9ad666
In the View.compare_builds (/compare/..), do not display "XX opam packages unchanged". The reasoning is that the diff view concerns: (a) opam packages (b) environment variables (c) system packages And we're only interested in what changed in each category. The list of unchanged opam packages is not really of interest, but adds quite some noise to the page.
129 lines
4.2 KiB
OCaml
129 lines
4.2 KiB
OCaml
module Set = OpamPackage.Set
|
|
|
|
type package = OpamPackage.t
|
|
|
|
let packages (switch : OpamFile.SwitchExport.t) =
|
|
assert (Set.cardinal switch.selections.sel_pinned = 0);
|
|
assert (Set.cardinal switch.selections.sel_compiler = 0);
|
|
assert (Set.subset switch.selections.sel_roots switch.selections.sel_installed);
|
|
switch.selections.sel_installed
|
|
|
|
type version_diff = {
|
|
name : OpamPackage.Name.t;
|
|
version_left : OpamPackage.Version.t;
|
|
version_right : OpamPackage.Version.t;
|
|
}
|
|
|
|
let pp_opampackage ppf p =
|
|
Format.fprintf ppf "%s" (OpamPackage.to_string p)
|
|
|
|
let pp_version_diff ppf { name; version_left; version_right } =
|
|
Format.fprintf ppf "%s.%s->%s"
|
|
(OpamPackage.Name.to_string name)
|
|
(OpamPackage.Version.to_string version_left)
|
|
(OpamPackage.Version.to_string version_right)
|
|
|
|
type opam_diff = {
|
|
pkg : OpamPackage.t ;
|
|
build : (OpamTypes.command list * OpamTypes.command list) option ;
|
|
install : (OpamTypes.command list * OpamTypes.command list) option ;
|
|
url : (OpamFile.URL.t option * OpamFile.URL.t option) option ;
|
|
otherwise_equal : bool ;
|
|
}
|
|
|
|
let commands_to_strings (l, r) =
|
|
let v a =
|
|
OpamPrinter.FullPos.value (OpamPp.print OpamFormat.V.command a)
|
|
in
|
|
List.map v l, List.map v r
|
|
|
|
let opt_url_to_string (l, r) =
|
|
let url_to_s = function
|
|
| None -> "" | Some u -> OpamFile.URL.write_to_string u
|
|
in
|
|
url_to_s l, url_to_s r
|
|
|
|
let pp_opam_diff ppf { pkg ; otherwise_equal ; _ } =
|
|
Format.fprintf ppf "%a%s"
|
|
pp_opampackage pkg
|
|
(if otherwise_equal then "" else " (and additional changes)")
|
|
|
|
let rec strip_common_prefix a b =
|
|
match a, b with
|
|
| hd::tl, hd'::tl' ->
|
|
if hd = hd' then
|
|
strip_common_prefix tl tl'
|
|
else
|
|
a, b
|
|
| a, b -> a, b
|
|
|
|
let detailed_opam_diff pkg l r =
|
|
let no_build_install_url p =
|
|
OpamFile.OPAM.with_url_opt None
|
|
(OpamFile.OPAM.with_install []
|
|
(OpamFile.OPAM.with_build [] p))
|
|
in
|
|
let otherwise_equal =
|
|
OpamFile.OPAM.effectively_equal
|
|
(no_build_install_url l) (no_build_install_url r)
|
|
and build =
|
|
if OpamFile.OPAM.build l = OpamFile.OPAM.build r then
|
|
None
|
|
else
|
|
Some (strip_common_prefix (OpamFile.OPAM.build l) (OpamFile.OPAM.build r))
|
|
and install =
|
|
if OpamFile.OPAM.install l = OpamFile.OPAM.install r then
|
|
None
|
|
else
|
|
Some (strip_common_prefix (OpamFile.OPAM.install l) (OpamFile.OPAM.install r))
|
|
and url =
|
|
if OpamFile.OPAM.url l = OpamFile.OPAM.url r then
|
|
None
|
|
else
|
|
Some (OpamFile.OPAM.url l, OpamFile.OPAM.url r)
|
|
in
|
|
{ pkg ; build ; install ; url ; otherwise_equal }
|
|
|
|
let detailed_opam_diffs left right pkgs =
|
|
OpamPackage.Set.fold (fun p acc ->
|
|
let find = OpamPackage.Name.Map.find p.name in
|
|
let opam_left = find left.OpamFile.SwitchExport.overlays
|
|
and opam_right = find right.OpamFile.SwitchExport.overlays in
|
|
(detailed_opam_diff p opam_left opam_right) :: acc)
|
|
pkgs []
|
|
|
|
let compare left right =
|
|
let packages_left = packages left and packages_right = packages right in
|
|
let module Set = OpamPackage.Set in
|
|
let equal_name p1 p2 = OpamPackage.Name.equal p1.OpamPackage.name p2.OpamPackage.name in
|
|
let diff l r =
|
|
Set.filter (fun p1 ->
|
|
not (Set.exists (equal_name p1) r))
|
|
l
|
|
in
|
|
let same_version = Set.inter packages_left packages_right in
|
|
let opam_diff =
|
|
Set.filter
|
|
(fun p ->
|
|
let find = OpamPackage.Name.Map.find p.name in
|
|
let opam_left = find left.overlays and opam_right = find right.overlays in
|
|
not (OpamFile.OPAM.effectively_equal opam_left opam_right))
|
|
same_version
|
|
and version_diff =
|
|
List.filter_map (fun p1 ->
|
|
match Set.find_opt (equal_name p1) packages_right with
|
|
| Some p2 ->
|
|
if OpamPackage.Version.equal p1.version p2.version
|
|
then None
|
|
else
|
|
Some { name = p1.OpamPackage.name;
|
|
version_left = p1.OpamPackage.version;
|
|
version_right = p2.OpamPackage.version }
|
|
| None ->
|
|
None)
|
|
(Set.elements packages_left)
|
|
and left_pkgs = diff packages_left packages_right
|
|
and right_pkgs = diff packages_right packages_left
|
|
in
|
|
let opam_diff = detailed_opam_diffs left right opam_diff in
|
|
(opam_diff, version_diff, left_pkgs, right_pkgs)
|