From fcc3f9e2110f3018b3db005bbbc6abeb2eaabce5 Mon Sep 17 00:00:00 2001 From: Raja Boujbel Date: Thu, 18 Nov 2021 14:31:37 +0100 Subject: [PATCH 1/5] OpamCompat: add Int module for compare --- src/core/opamCompat.ml | 9 +++++++++ src/core/opamCompat.mli | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/core/opamCompat.ml b/src/core/opamCompat.ml index 98c698900cd..7314a748168 100644 --- a/src/core/opamCompat.ml +++ b/src/core/opamCompat.ml @@ -23,6 +23,15 @@ struct end #endif +module Int = +#if OCAML_VERSION >= (4, 6, 0) + Int +#else +struct + let compare : int -> int -> int = Stdlib.compare +end +#endif + module Printexc = #if OCAML_VERSION >= (4, 5, 0) Printexc diff --git a/src/core/opamCompat.mli b/src/core/opamCompat.mli index 2e84d17712c..1956a47094e 100644 --- a/src/core/opamCompat.mli +++ b/src/core/opamCompat.mli @@ -23,6 +23,15 @@ module Either end #endif +module Int +#if OCAML_VERSION >= (4, 12, 0) += Int +#else +: sig + val compare: int -> int -> int +end +#endif + module Printexc #if OCAML_VERSION >= (4, 5, 0) = Printexc From d10ed3d838a27b565214f0d4b16dfb7b58348b62 Mon Sep 17 00:00:00 2001 From: Raja Boujbel Date: Wed, 17 Nov 2021 17:18:03 +0100 Subject: [PATCH 2/5] add compare function to some modules --- src/client/opamCLIVersion.ml | 7 ++++++- src/core/opamCompat.ml | 2 +- src/core/opamFilename.ml | 22 ++++++++++++++++++++++ src/core/opamHash.ml | 8 ++++++++ src/core/opamStd.ml | 8 ++++++-- src/core/opamStd.mli | 2 ++ src/core/opamUrl.ml | 11 +++++++++++ src/core/opamVersion.ml | 1 + src/format/opamSysPkg.ml | 1 + src/format/opamVariable.ml | 13 +++++++++++++ 10 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/client/opamCLIVersion.ml b/src/client/opamCLIVersion.ml index a3b09655a31..ee27145216d 100644 --- a/src/client/opamCLIVersion.ml +++ b/src/client/opamCLIVersion.ml @@ -41,7 +41,12 @@ let of_json = function let ( >= ) = Stdlib.( >= ) let ( < ) = Stdlib.( < ) -let compare = Stdlib.compare +let compare (vm, vn) (wm, wn) = + let open OpamCompat in + let major = Int.compare vm wm in + if major <> 0 then major else + Int.compare vn wn +let equal v w = compare v w = 0 let previous cli = let f previous version = diff --git a/src/core/opamCompat.ml b/src/core/opamCompat.ml index 7314a748168..f664d89ae05 100644 --- a/src/core/opamCompat.ml +++ b/src/core/opamCompat.ml @@ -24,7 +24,7 @@ end #endif module Int = -#if OCAML_VERSION >= (4, 6, 0) +#if OCAML_VERSION >= (4, 8, 0) Int #else struct diff --git a/src/core/opamFilename.ml b/src/core/opamFilename.ml index 011c0156813..ede660a5876 100644 --- a/src/core/opamFilename.ml +++ b/src/core/opamFilename.ml @@ -12,6 +12,9 @@ module Base = struct include OpamStd.AbstractString + let compare = String.compare + let equal = String.equal + let check_suffix filename s = Filename.check_suffix filename s @@ -26,6 +29,9 @@ module Dir = struct include OpamStd.AbstractString + let compare = String.compare + let equal = String.equal + let of_string dirname = let dirname = if dirname = "~" then OpamStd.Sys.home () @@ -473,6 +479,13 @@ let of_json = function | `String x -> (try Some (of_string x) with _ -> None) | _ -> None +let compare f g = + let dir = Dir.compare f.dirname g.dirname in + if dir <> 0 then dir else + Base.compare f.basename g.basename + +let equal f g = compare f g = 0 + module O = struct type tmp = t type t = tmp @@ -561,6 +574,15 @@ module Attribute = struct end | _ -> None + let compare a b = + let base = Base.compare a.base b.base in + if base <> 0 then base else + let md5 = OpamHash.compare a.md5 b.md5 in + if md5 <> 0 then md5 else + OpamStd.Option.compare OpamCompat.Int.compare a.perm b.perm + + let equal a b = compare a b = 0 + module O = struct type tmp = t type t = tmp diff --git a/src/core/opamHash.ml b/src/core/opamHash.ml index bb9fb310a2a..1df6bd50bad 100644 --- a/src/core/opamHash.ml +++ b/src/core/opamHash.ml @@ -17,6 +17,14 @@ type t = kind * string let kind = fst let contents = snd +let compare (k,h) (l,i) = + match k, l with + | `SHA512, `SHA512 | `SHA256, `SHA256 | `MD5, `MD5 -> String.compare h i + | `MD5, _ | _, `SHA512 -> -1 + | `SHA512, _ | _, `MD5 -> 1 + +let equal h h' = compare h h' = 0 + let log msg = OpamConsole.log "HASH" msg let pfx_sep_char = '=' diff --git a/src/core/opamStd.ml b/src/core/opamStd.ml index fa5f6eea3fd..07c18de69bb 100644 --- a/src/core/opamStd.ml +++ b/src/core/opamStd.ml @@ -50,6 +50,8 @@ module type MAP = sig end module type ABSTRACT = sig type t + val compare: t -> t -> int + val equal: t -> t -> bool val of_string: string -> t val to_string: t -> string val to_json: t -> OpamJson.t @@ -384,6 +386,8 @@ end module AbstractString = struct type t = string + let compare = String.compare + let equal = String.equal let of_string x = x let to_string x = x let to_json x = `String x @@ -404,7 +408,7 @@ end module OInt = struct type t = int - let compare = compare + let compare = OpamCompat.Int.compare let to_string = string_of_int let to_json i = `String (string_of_int i) let of_json = function @@ -483,7 +487,7 @@ module OpamString = struct module OString = struct type t = string - let compare = compare + let compare = String.compare let to_string x = x let to_json x = `String x let of_json = function diff --git a/src/core/opamStd.mli b/src/core/opamStd.mli index e8321c94f34..b383c34e285 100644 --- a/src/core/opamStd.mli +++ b/src/core/opamStd.mli @@ -100,6 +100,8 @@ module type ABSTRACT = sig type t + val compare: t -> t -> int + val equal: t -> t -> bool val of_string: string -> t val to_string: t -> string val to_json: t -> OpamJson.t diff --git a/src/core/opamUrl.ml b/src/core/opamUrl.ml index cd406804476..a23b081a97e 100644 --- a/src/core/opamUrl.ml +++ b/src/core/opamUrl.ml @@ -29,6 +29,17 @@ let empty = { hash = None; } +let compare u v = + let transport = String.compare u.transport v.transport in + if transport <> 0 then transport else + let path = String.compare u.path v.path in + if path <> 0 then path else + let hash = OpamStd.Option.compare String.compare u.hash v.hash in + if hash <> 0 then hash else + compare u.backend v.backend + +let equal u v = compare u v = 0 + exception Parse_error of string let parse_error s = raise (Parse_error s) diff --git a/src/core/opamVersion.ml b/src/core/opamVersion.ml index 0b275f3f0d0..4d11301743b 100644 --- a/src/core/opamVersion.ml +++ b/src/core/opamVersion.ml @@ -22,6 +22,7 @@ let of_json = function | _ -> None let compare v w = OpamVersionCompare.compare v w +let equal v w = compare v w = 0 module O = struct type t = string diff --git a/src/format/opamSysPkg.ml b/src/format/opamSysPkg.ml index 14c7a384b3f..d77187a6ea4 100644 --- a/src/format/opamSysPkg.ml +++ b/src/format/opamSysPkg.ml @@ -15,6 +15,7 @@ type t = string let of_string s = s let to_string s = s let compare = OpamStd.String.compare_case +let equal s r = compare s r = 0 let to_json s = `O [ ("sys_package", `String s) ] diff --git a/src/format/opamVariable.ml b/src/format/opamVariable.ml index 3ae74657d52..6441cd7fb4e 100644 --- a/src/format/opamVariable.ml +++ b/src/format/opamVariable.ml @@ -108,6 +108,19 @@ module Full = struct | `String s -> (try Some (of_string s) with _ -> None) | _ -> None + let compare f g = + match f.scope, g.scope with + | Global, Global | Self, Self -> + String.compare f.variable g.variable + | Package n, Package m -> + let package = OpamPackage.Name.compare n m in + if package <> 0 then package else + String.compare f.variable g.variable + | Global, _ | _, Self -> 1 + | Self, _ | _, Global -> -1 + + let equal f g = compare f g = 0 + module O = struct type tmp = t type t = tmp From d006e15e82664b77c7775e583d961b65fbeaf88f Mon Sep 17 00:00:00 2001 From: "R. Boujbel" Date: Fri, 19 Nov 2021 12:12:22 +0100 Subject: [PATCH 3/5] expose records in comparison function to trigger record changes --- src/core/opamFilename.ml | 14 +++++++------- src/core/opamUrl.ml | 10 +++++----- src/format/opamVariable.ml | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/opamFilename.ml b/src/core/opamFilename.ml index ede660a5876..48a84053f99 100644 --- a/src/core/opamFilename.ml +++ b/src/core/opamFilename.ml @@ -479,10 +479,10 @@ let of_json = function | `String x -> (try Some (of_string x) with _ -> None) | _ -> None -let compare f g = - let dir = Dir.compare f.dirname g.dirname in +let compare {dirname; basename} f = + let dir = Dir.compare dirname f.dirname in if dir <> 0 then dir else - Base.compare f.basename g.basename + Base.compare basename f.basename let equal f g = compare f g = 0 @@ -574,12 +574,12 @@ module Attribute = struct end | _ -> None - let compare a b = - let base = Base.compare a.base b.base in + let compare {base; md5; perm} a = + let base = Base.compare base a.base in if base <> 0 then base else - let md5 = OpamHash.compare a.md5 b.md5 in + let md5 = OpamHash.compare md5 a.md5 in if md5 <> 0 then md5 else - OpamStd.Option.compare OpamCompat.Int.compare a.perm b.perm + OpamStd.Option.compare OpamCompat.Int.compare perm a.perm let equal a b = compare a b = 0 diff --git a/src/core/opamUrl.ml b/src/core/opamUrl.ml index a23b081a97e..5e2582d842c 100644 --- a/src/core/opamUrl.ml +++ b/src/core/opamUrl.ml @@ -29,14 +29,14 @@ let empty = { hash = None; } -let compare u v = - let transport = String.compare u.transport v.transport in +let compare {transport; path; hash; backend} u = + let transport = String.compare transport u.transport in if transport <> 0 then transport else - let path = String.compare u.path v.path in + let path = String.compare path u.path in if path <> 0 then path else - let hash = OpamStd.Option.compare String.compare u.hash v.hash in + let hash = OpamStd.Option.compare String.compare hash u.hash in if hash <> 0 then hash else - compare u.backend v.backend + compare backend u.backend let equal u v = compare u v = 0 diff --git a/src/format/opamVariable.ml b/src/format/opamVariable.ml index 6441cd7fb4e..bb59d10630a 100644 --- a/src/format/opamVariable.ml +++ b/src/format/opamVariable.ml @@ -108,14 +108,14 @@ module Full = struct | `String s -> (try Some (of_string s) with _ -> None) | _ -> None - let compare f g = - match f.scope, g.scope with + let compare {scope; variable} fv = + match scope, fv.scope with | Global, Global | Self, Self -> - String.compare f.variable g.variable + String.compare variable fv.variable | Package n, Package m -> let package = OpamPackage.Name.compare n m in if package <> 0 then package else - String.compare f.variable g.variable + String.compare variable fv.variable | Global, _ | _, Self -> 1 | Self, _ | _, Global -> -1 From db3150b3eb3b7dbaa2c75de796c599ad6b055318 Mon Sep 17 00:00:00 2001 From: Raja Boujbel Date: Wed, 17 Nov 2021 21:04:39 +0100 Subject: [PATCH 4/5] crowbar: update with new compare functions --- src/crowbar/opamFilename_crowbar.ml | 6 +++--- src/crowbar/opamHash_crowbar.ml | 2 +- src/crowbar/opamUrl_crowbar.ml | 2 +- src/crowbar/opamVariable_crowbar.ml | 3 +-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/crowbar/opamFilename_crowbar.ml b/src/crowbar/opamFilename_crowbar.ml index 409876b5335..85dff49220f 100644 --- a/src/crowbar/opamFilename_crowbar.ml +++ b/src/crowbar/opamFilename_crowbar.ml @@ -32,8 +32,8 @@ let filename : t gen = let check () = check_json_roundtrip ~name:"OpamFilename.Base.t" - base (=) Base.to_json Base.of_json; + base (eq_of_comp Base.compare) Base.to_json Base.of_json; check_json_roundtrip ~name:"OpamFilename.Dir.t" - dir (=) Dir.to_json Dir.of_json; + dir (eq_of_comp Dir.compare) Dir.to_json Dir.of_json; check_json_roundtrip ~name:"OpamFilename.t" - filename (=) to_json of_json; + filename (eq_of_comp OpamFilename.compare) to_json of_json; diff --git a/src/crowbar/opamHash_crowbar.ml b/src/crowbar/opamHash_crowbar.ml index d52bca2890b..34bf234367b 100644 --- a/src/crowbar/opamHash_crowbar.ml +++ b/src/crowbar/opamHash_crowbar.ml @@ -23,4 +23,4 @@ let hash = map [kind; bytes] @@ fun kind string -> let check () = check_json_roundtrip ~name:"OpamHash.t" - hash (=) OpamHash.to_json OpamHash.of_json; + hash (eq_of_comp OpamHash.compare) OpamHash.to_json OpamHash.of_json; diff --git a/src/crowbar/opamUrl_crowbar.ml b/src/crowbar/opamUrl_crowbar.ml index 57e65d61abf..d0c606deffd 100644 --- a/src/crowbar/opamUrl_crowbar.ml +++ b/src/crowbar/opamUrl_crowbar.ml @@ -49,4 +49,4 @@ let url : OpamUrl.t gen = map [ let check () = check_json_roundtrip ~name:"OpamUrl.t" - url (=) OpamUrl.to_json OpamUrl.of_json; + url (eq_of_comp OpamUrl.compare) OpamUrl.to_json OpamUrl.of_json; diff --git a/src/crowbar/opamVariable_crowbar.ml b/src/crowbar/opamVariable_crowbar.ml index 68be9200cbc..be5b5812e5c 100644 --- a/src/crowbar/opamVariable_crowbar.ml +++ b/src/crowbar/opamVariable_crowbar.ml @@ -21,6 +21,5 @@ let full = choose [ ] let check () = - let equal v1 v2 = Full.to_string v1 = Full.to_string v2 in check_json_roundtrip ~name:"OpamVariable.t" - full equal Full.to_json Full.of_json; + full (eq_of_comp OpamVariable.Full.compare) Full.to_json Full.of_json; From 885b1fd58b4558c730e071e353118411d9d34029 Mon Sep 17 00:00:00 2001 From: Raja Boujbel Date: Wed, 17 Nov 2021 20:59:16 +0100 Subject: [PATCH 5/5] update changes --- master_changes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/master_changes.md b/master_changes.md index 6d3b2cfd2a6..a2e813eb807 100644 --- a/master_changes.md +++ b/master_changes.md @@ -138,6 +138,7 @@ users) ## Internal * Add license and lowerbounds to opam files [#4714 @kit-ty-kate] * Bump version to 2.2.0~alpha~dev [#4725 @dra27] + * Add specific comparison function on several module (that includes `OpamStd.ABSTRACT`) [#4918 @rjbou] ## Internal: Windows * Support MSYS2: treat MSYS2 and Cygwin as equivalent [#4813 @jonahbeckford] @@ -145,6 +146,7 @@ users) * [BUG] handle converted variables correctly when no_undef_expand is true [#4811 @timbertson] ## Test + * Update crowbar with compare functions [#4918 @rjbou] ## Reftests * Add switch-invariant test [#4866 @rjbou] @@ -177,9 +179,13 @@ users) # API updates ## opam-client + * `OpamStd.ABSTRACT`: add `compare` and `equal`, that added those functions to `OpamCLIVersion` [#4918 @rjbou] ## opam-repository ## opam-state ## opam-solver ## opam-format + * `OpamStd.ABSTRACT`: add `compare` and `equal`, that added those functions to `OpamSysPkg` and `OpamVariable` [#4918 @rjbou] ## opam-core * OpamSystem: avoid calling Unix.environment at top level [#4789 @hannesm] + * `OpamStd.ABSTRACT`: add `compare` and `equal`, that added those functions to `OpamFilename`, `OpamHash`, `OpamStd`, `OpamStd`, `OpamUrl`, and `OpamVersion` [#4918 @rjbou] +