From 60c94c0554ba79e375233f4d4783e58a77e626c7 Mon Sep 17 00:00:00 2001 From: Sylvain Ribstein Date: Fri, 5 Apr 2024 10:38:58 +0200 Subject: [PATCH 1/2] clic: fix clic behavior on multiple occur arg --- CHANGES.rst | 5 ++++- src/lib_clic/tezos_clic.ml | 7 ++++--- tezt/lib_tezos/client.ml | 6 ++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 080644a26eeb..ffa112463799 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -129,7 +129,7 @@ Baker - Fixed situations where the baker would stall when a signing request hanged. (MR :gl:`!12353`) -- Introduced two new nonces files (``_stateful_nonces`` and +- Introduced two new nonces files (``_stateful_nonces`` and ``_orphaned_nonces``). Each nonce is registered with a state for optimising the nonce lookup, reducing the number of rpc calls required to calculate nonce revelations. (MR :gl:`!12517`) @@ -222,3 +222,6 @@ Miscellaneous overflow. - Versions now include information about the product. (MR :gl:`!12366`) + +- **Breaking change** Multiple occurrence of same argument now + fails when using ``lib-clic``. (MR :gl:`!12780`) diff --git a/src/lib_clic/tezos_clic.ml b/src/lib_clic/tezos_clic.ml index c5217516f6c8..41de7a9662f9 100644 --- a/src/lib_clic/tezos_clic.ml +++ b/src/lib_clic/tezos_clic.ml @@ -1044,9 +1044,10 @@ let check_version_flag = | _ -> return_unit let add_occurrence long value acc = - match StringMap.find_opt long acc with - | Some v -> StringMap.add long v acc - | None -> StringMap.add long [value] acc + StringMap.update + long + (function Some v -> Some (v @ [value]) | None -> Some [value]) + acc let make_args_dict_consume ?command spec args = let open Lwt_result_syntax in diff --git a/tezt/lib_tezos/client.ml b/tezt/lib_tezos/client.ml index 281cf2efb961..d6702397b46b 100644 --- a/tezt/lib_tezos/client.ml +++ b/tezt/lib_tezos/client.ml @@ -2336,7 +2336,7 @@ let spawn_list_protocols mode client = | `Light -> "light" | `Proxy -> "proxy" in - spawn_command client (mode_arg client @ ["list"; mode_str; "protocols"]) + spawn_command client ["list"; mode_str; "protocols"] let list_protocols mode client = let* output = @@ -2358,9 +2358,7 @@ let list_understood_protocols ?config_file client = return (parse_list_protocols_output output) let spawn_migrate_mockup ~next_protocol client = - spawn_command - client - (mode_arg client @ ["migrate"; "mockup"; "to"; Protocol.hash next_protocol]) + spawn_command client ["migrate"; "mockup"; "to"; Protocol.hash next_protocol] let migrate_mockup ~next_protocol client = spawn_migrate_mockup ~next_protocol client |> Process.check -- GitLab From 5689f1e6aca69ab2bdbe7e8eb986d9aa23c9c393 Mon Sep 17 00:00:00 2001 From: Sylvain Ribstein Date: Wed, 3 Apr 2024 17:25:30 +0200 Subject: [PATCH 2/2] clic: add multiple occurence arg possibility --- src/lib_clic/tezos_clic.ml | 53 ++++++++++++++++++++++++++++++++++--- src/lib_clic/tezos_clic.mli | 14 ++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/lib_clic/tezos_clic.ml b/src/lib_clic/tezos_clic.ml index 41de7a9662f9..951ae14d6829 100644 --- a/src/lib_clic/tezos_clic.ml +++ b/src/lib_clic/tezos_clic.ml @@ -86,6 +86,13 @@ type ('a, 'ctx) arg = kind : ('p, 'ctx) parameter; } -> ('p option, 'ctx) arg + | MultipleArg : { + doc : string; + label : label; + placeholder : string; + kind : ('p, 'ctx) parameter; + } + -> ('p list option, 'ctx) arg | DefArg : { doc : string; label : label; @@ -195,6 +202,15 @@ let rec print_options_detailed : placeholder print_desc doc + | MultipleArg {label; placeholder; doc; _} -> + Format.fprintf + ppf + "@{%a <%s>@}: %a" + print_label + label + placeholder + print_desc + doc | DefArg {label; placeholder; doc; default; _} -> Format.fprintf ppf @@ -219,7 +235,7 @@ let rec print_options_detailed : let rec has_args : type a ctx. (a, ctx) arg -> bool = function | Constant _ -> false - | Arg _ | DefArg _ | Switch _ -> true + | Arg _ | MultipleArg _ | DefArg _ | Switch _ -> true | Pair (speca, specb) -> has_args speca || has_args specb | Map {spec; _} -> has_args spec @@ -230,6 +246,8 @@ let rec print_options_brief : Format.fprintf ppf "[@{%a <%s>@}]" print_label label placeholder | Arg {label; placeholder; _} -> Format.fprintf ppf "[@{%a <%s>@}]" print_label label placeholder + | MultipleArg {label; placeholder; _} -> + Format.fprintf ppf "[@{%a <%s>@}]" print_label label placeholder | Switch {label; _} -> Format.fprintf ppf "[@{%a@}]" print_label label | Constant _ -> () | Pair (speca, specb) -> @@ -759,6 +777,9 @@ let constant c = Constant c let arg ~doc ?short ~long ~placeholder kind = Arg {doc; label = {long; short}; placeholder; kind} +let multiple_arg ~doc ?short ~long ~placeholder kind = + MultipleArg {doc; label = {long; short}; placeholder; kind} + let default_arg ~doc ?short ~long ~placeholder ~default kind = DefArg {doc; placeholder; label = {long; short}; kind; default} @@ -975,6 +996,19 @@ let rec parse_arg : in Some x | Some (_ :: _) -> tzfail (Multiple_occurrences ("--" ^ long, command))) + | MultipleArg {label = {long; short = _}; kind = {converter; _}; _} -> ( + match StringMap.find_opt long args_dict with + | None | Some [] -> return_none + | Some l -> + let+ x = + List.map_es + (fun s -> + trace_eval (fun () -> + Bad_option_argument ("--" ^ long, command)) + @@ converter ctx s) + l + in + Some x) | DefArg {label = {long; short = _}; kind = {converter; _}; default; _} -> ( let*! r = converter ctx default in match r with @@ -1019,6 +1053,7 @@ let rec make_arities_dict : in match arg with | Arg {label; _} -> add label 1 + | MultipleArg {label; _} -> add label 1 | DefArg {label; _} -> add label 1 | Switch {label; _} -> add label 0 | Constant _c -> acc @@ -1465,7 +1500,11 @@ let get_arg {long; short} = let rec list_args : type a ctx. (a, ctx) arg -> string list = function | Constant _ -> [] - | Arg {label; _} | DefArg {label; _} | Switch {label; _} -> get_arg label + | Arg {label; _} + | MultipleArg {label; _} + | DefArg {label; _} + | Switch {label; _} -> + get_arg label | Pair (speca, specb) -> list_args speca @ list_args specb | Map {spec; _} -> list_args spec @@ -1481,7 +1520,10 @@ let rec remaining_spec : type a ctx. StringSet.t -> (a, ctx) arg -> string list = fun seen -> function | Constant _ -> [] - | Arg {label; _} | DefArg {label; _} | Switch {label; _} -> + | Arg {label; _} + | MultipleArg {label; _} + | DefArg {label; _} + | Switch {label; _} -> if StringSet.mem label.long seen then [] else get_arg label | Pair (speca, specb) -> remaining_spec seen speca @ remaining_spec seen specb | Map {spec; _} -> remaining_spec seen spec @@ -1499,8 +1541,11 @@ let complete_options (type ctx) continuation args args_spec ind (ctx : ctx) = when label.long = name -> let* p = complete_func autocomplete ctx in return_some p + | MultipleArg {kind = {autocomplete; _}; label; _} when label.long = name -> + let* p = complete_func autocomplete ctx in + return_some p | Switch {label; _} when label.long = name -> return_some [] - | Arg _ | DefArg _ | Switch _ -> return_none + | Arg _ | MultipleArg _ | DefArg _ | Switch _ -> return_none | Pair (speca, specb) -> ( let* resa = complete_spec name speca in match resa with diff --git a/src/lib_clic/tezos_clic.mli b/src/lib_clic/tezos_clic.mli index c4e7a57e5576..39734ce5ba8c 100644 --- a/src/lib_clic/tezos_clic.mli +++ b/src/lib_clic/tezos_clic.mli @@ -100,6 +100,20 @@ val arg : ('a, 'ctx) parameter -> ('a option, 'ctx) arg +(** [multiple_arg ~doc ~long ?short converter] creates an argument to + a command. The [~long] argument is the long format, without the + double dashes. The [?short] argument is the optional one letter + shortcut. If the argument is not provided, [None] is + returned. Multiple occurrence of the argument is allowed in the + command. *) +val multiple_arg : + doc:string -> + ?short:char -> + long:string -> + placeholder:string -> + ('a, 'ctx) parameter -> + ('a list option, 'ctx) arg + (** Create an argument that will contain the [~default] value if it is not provided. *) val default_arg : doc:string -> -- GitLab