Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an admin command to compare 2 package versions #6124

Closed
wants to merge 12 commits into from
11 changes: 11 additions & 0 deletions doc/man/opam-admin-topics.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions master_changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ users)
* Bump opam-root-version to 2.2 [#5980 @kit-ty-kate]

## Global CLI
* ◈ Add `opam admin compare-versions` to compare package versions for sanity checks [#6124 @mbarbin]
* Add cli version 2.3 [#6045 #6151 @rjbou]

## Plugins
Expand Down
67 changes: 67 additions & 0 deletions src/client/opamAdminCommand.ml
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,72 @@ 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 2 package versions"
let compare_versions_command cli =
let operators =
List.map (fun op -> OpamFormula.string_of_relop op, op)
OpamFormula.all_relop
in
let assert_result =
let doc =
Arg.info
~docv:"OP"
~doc:(Printf.sprintf
"When supplied, the output is suppressed and the result of \
the comparison is checked againts the provided operator. \
The command exits 0 if the comparison holds, and 1 otherwise. \
$(docv) must be %s.\n" (Arg.doc_alts_enum ~quoted:true operators))
[ "assert" ]
in
Arg.(value & opt (some (enum operators)) None doc)
in
let version_arg n =
let doc =
Arg.info
~docv:(Printf.sprintf "VERSION%d" (n+1))
~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 for quick sanity checks. \
By default it prints the result of the comparison to the console. \
You may optionally control the exit-code with '--assert=OP'. \
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 0.0.10 --assert='<'\n\
[0]\n\
\n\
\\$ opam admin compare-versions 0.0.9 0.0.10 --assert='>='\n\
[1]";
`S Manpage.s_arguments;
`S Manpage.s_options;
]
in
let cmd global_options v1 v2 assert_result () =
OpamArg.apply_global_options cli global_options;
match assert_result with
| None ->
let result = OpamPackage.Version.compare v1 v2 in
OpamConsole.formatted_msg "%s %s %s\n"
(OpamPackage.Version.to_string v1)
(if result < 0 then "<" else if result = 0 then "=" else ">")
(OpamPackage.Version.to_string v2)
| Some op ->
OpamStd.Sys.exit_because
(if OpamFormula.eval_relop op v1 v2
then `Success
else `False)
in
OpamArg.mk_command ~cli OpamArg.cli_original command ~doc ~man
Term.(const cmd $ global_options cli $ version_arg 0 $ version_arg 1 $ assert_result)

let pattern_list_arg =
OpamArg.arg_list "PATTERNS"
"Package patterns with globs. matching against $(b,NAME) or \
Expand Down Expand Up @@ -1227,6 +1293,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;
Expand Down
2 changes: 2 additions & 0 deletions src/format/opamFormula.ml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ let neg_relop = function

let string_of_relop = OpamPrinter.FullPos.relop_kind

let all_relop = [ `Eq ; `Neq ; `Geq ; `Gt ; `Leq ; `Lt ]

type version_constraint = relop * OpamPackage.Version.t

type atom = OpamPackage.Name.t * version_constraint option
Expand Down
7 changes: 7 additions & 0 deletions src/format/opamFormula.mli
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ type relop = OpamParserTypes.FullPos.relop_kind (* = [ `Eq | `Neq | `Geq | `Gt |

val compare_relop : relop -> relop -> int

(** A list containing each available operator once. *)
val all_relop : relop list

(** Returns a string representing the operator in infix syntax, as
used in opam files (">", "=", etc.) *)
val string_of_relop : relop -> string

(** Version constraints for OPAM *)
type version_constraint = relop * OpamPackage.Version.t

Expand Down
22 changes: 22 additions & 0 deletions tests/reftests/compare-versions.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
N0REP0
### 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 0.1.0 0.01.0
0.1.0 = 0.01.0
### opam admin compare-versions 0.1.0 0.01.0 --assert '='
### opam admin compare-versions 0.0.9 0.0.10 --assert '<'
### opam admin compare-versions 0.0.9 0.0.10 --assert '<='
### opam admin compare-versions 1.2.3 1.2.3~preview --assert '>'
### opam admin compare-versions 1.2.3 1.2.3~preview --assert '>='
### opam admin compare-versions 0.0.9 0.0.10 --assert '='
# Return code 1 #
### opam admin compare-versions 1.2.3 1.2.3~preview --assert '<'
# Return code 1 #
### opam admin compare-versions 1.2.3-option 1.2.3 --assert '<='
# Return code 1 #
### opam admin compare-versions 0.0.9 0.0.10 --assert '>'
# Return code 1 #
### opam admin compare-versions 0.0.9 0.0.10 --assert '>='
# Return code 1 #
18 changes: 18 additions & 0 deletions tests/reftests/dune.inc
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,24 @@
%{targets}
(run ./run.exe %{exe:../../src/client/opamMain.exe.exe} %{dep:cli-versioning.test} %{read-lines:testing-env}))))

(rule
(alias reftest-compare-versions)
(action
(diff compare-versions.test compare-versions.out)))

(alias
(name reftest)
(deps (alias reftest-compare-versions)))

(rule
(targets compare-versions.out)
(deps root-N0REP0)
(package opam)
(action
(with-stdout-to
%{targets}
(run ./run.exe %{exe:../../src/client/opamMain.exe.exe} %{dep:compare-versions.test} %{read-lines:testing-env}))))

(rule
(alias reftest-config)
(enabled_if (and (or (<> %{env:TESTALL=1} 0) (= %{env:TESTN0REP0=0} 1))))
Expand Down
Loading