diff --git a/doc/man/opam-admin-topics.inc b/doc/man/opam-admin-topics.inc index c2618ecb6cf..ffbb4aed863 100644 --- a/doc/man/opam-admin-topics.inc +++ b/doc/man/opam-admin-topics.inc @@ -60,6 +60,16 @@ (diff opam-admin-list.err %{dep:opam-admin-list.0}))) (package opam)) +(rule + (with-stdout-to opam-admin-compare-versions.0 (echo ""))) +(rule + (targets opam-admin-compare-versions.1 opam-admin-compare-versions.err) + (deps using-built-opam) + (action (progn (with-stderr-to opam-admin-compare-versions.err + (with-stdout-to opam-admin-compare-versions.1 (run %{bin:opam} admin compare-versions --help=groff))) + (diff opam-admin-compare-versions.err %{dep:opam-admin-compare-versions.0}))) + (package opam)) + (rule (with-stdout-to opam-admin-check.0 (echo ""))) (rule @@ -130,6 +140,7 @@ opam-admin-add-constraint.1 opam-admin-filter.1 opam-admin-list.1 + opam-admin-compare-versions.1 opam-admin-check.1 opam-admin-lint.1 opam-admin-upgrade.1 diff --git a/master_changes.md b/master_changes.md index 219e7180689..1aa9069f5ee 100644 --- a/master_changes.md +++ b/master_changes.md @@ -92,6 +92,7 @@ users) * Add opam 2.3.0\~beta2 to the install scripts [#6262 @kit-ty-kate] ## Admin + * ◈ Add `opam admin compare-versions` to compare package versions for sanity checks [#6197 @mbarbin] ## Opam installer diff --git a/src/client/opamAdminCommand.ml b/src/client/opamAdminCommand.ml index 38954d1c6b1..6bc2eeb0a7a 100644 --- a/src/client/opamAdminCommand.ml +++ b/src/client/opamAdminCommand.ml @@ -830,6 +830,71 @@ let check_command cli = Term.(const cmd $ global_options cli $ ignore_test_arg $ print_short_arg $ installability_arg $ cycles_arg $ obsolete_arg) +let compare_versions_command_doc = "Compare two package versions" +let compare_versions_command cli = + let operator : OpamFormula.relop option Term.t = + let make_flag (relop : OpamFormula.relop) = + let flag_name = + match relop with + | `Eq -> "eq" + | `Neq -> "neq" + | `Geq -> "geq" + | `Gt -> "gt" + | `Leq -> "leq" + | `Lt -> "lt" + in + let doc = Printf.sprintf "assert V0 %s V1" (OpamFormula.string_of_relop relop) in + OpamArg.(cli_from cli2_4), Some relop, [ flag_name ], doc + in + OpamArg.mk_vflag ~cli None (List.map make_flag OpamFormula.all_relop) + in + let version_arg n = + let doc = + Arg.info + ~docv:(Printf.sprintf "V%d" n) + ~doc:"Package version to compare" [] + in + Arg.(required & pos n (some OpamArg.package_version) None & doc) + in + let command = "compare-versions" in + let doc = compare_versions_command_doc in + let man = [ + `S Manpage.s_description; + `P "This command compares 2 package versions. By default it outputs 'V0 OP \ + V1' to the console with OP in {<,>,=} such that the equation holds. \ + When an operator is supplied, the output is suppressed and the result \ + of the comparison is checked against the provided operator: the command \ + exits 0 if the comparison holds, and 1 otherwise. For example:"; + `Pre "\n\ + \\$ opam admin compare-versions 0.0.9 0.0.10\n\ + 0.0.9 < 0.0.10\n\ + \n\ + \\$ opam admin compare-versions 0.0.9 --lt 0.0.10\n\ + [0]\n\ + \n\ + \\$ opam admin compare-versions 0.0.9 --eq 0.0.10\n\ + [1]"; + `S Manpage.s_arguments; + `S Manpage.s_options; + ] + in + let cmd v0 v1 operator () = + match operator with + | None -> + let result = OpamPackage.Version.compare v0 v1 in + OpamConsole.formatted_msg "%s %s %s\n" + (OpamPackage.Version.to_string v0) + (if result < 0 then "<" else if result = 0 then "=" else ">") + (OpamPackage.Version.to_string v1) + | Some operator -> + OpamStd.Sys.exit_because + (if OpamFormula.eval_relop operator v0 v1 + then `Success + else `False) + in + OpamArg.mk_command ~cli OpamArg.(cli_from cli2_4) command ~doc ~man + Term.(const cmd $ version_arg 0 $ version_arg 1 $ operator) + let pattern_list_arg = OpamArg.arg_list "PATTERNS" "Package patterns with globs. matching against $(b,NAME) or \ @@ -1227,6 +1292,7 @@ let admin_subcommands cli = upgrade_command cli; lint_command cli; check_command cli; + compare_versions_command cli; list_command cli; filter_command cli; add_constraint_command cli; diff --git a/tests/reftests/admin.test b/tests/reftests/admin.test index 558c2c0fb82..f81589d1d78 100644 --- a/tests/reftests/admin.test +++ b/tests/reftests/admin.test @@ -654,9 +654,31 @@ opam-version: "2.0" ### :::::::::::::::::::::::::::::::::::::::::::::::::::::: ### :: Cache is tested in admin-cache.test :: ### :::::::::::::::::::::::::::::::::::::::::::::::::::::: -### : +### ::::::::::::::::::::: +### :VII: compare-versions : +### ::::::::::::::::::::: +### opam admin compare-versions 0.0.9 0.0.10 +0.0.9 < 0.0.10 +### opam admin compare-versions 1.2.3 1.2.3~preview +1.2.3 > 1.2.3~preview +### opam admin compare-versions 1.2.3 1.2.3-option +1.2.3 < 1.2.3-option +### opam admin compare-versions 0.1.0 0.01.0 +0.1.0 = 0.01.0 +### opam admin compare-versions 0.2.2 0.2.0 +0.2.2 > 0.2.0 +### opam admin compare-versions 0.0.9 --lt 0.0.10 +### opam admin compare-versions 1.2.3 --lt 1.2.3~preview +# Return code 1 # +### opam admin compare-versions 0.1.0 --eq 0.01.0 +### opam admin compare-versions 0.0.9 --eq 0.0.10 +# Return code 1 # +### opam admin compare-versions 0.1.0 --le 0.1.0 +### opam admin compare-versions 0.0.9 --le 0.0.10 +### opam admin compare-versions 0.2.2 --le 0.2.1 +# Return code 1 # ### :::::::::::::::::::::: -### :VII: Specific cases : +### :C: Specific cases : ### :::::::::::::::::::::: ### : Package version comparison error (#5334) ###