From f3d2bd7c08b502ce37a54badb572a8e32c0f201b Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Tue, 25 Apr 2017 00:44:37 -0700 Subject: [PATCH] [subcommands] support subcommands without leading -- Summary: `infer diff ...` works now. Reviewed By: jberdine Differential Revision: D4921062 fbshipit-source-id: a8a37c2 --- infer/src/base/CommandLineOption.ml | 33 +++++++++++++++++++--------- infer/src/base/CommandLineOption.mli | 8 ++++--- infer/src/base/Config.ml | 5 +++-- infer/tests/differential.make | 2 +- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/infer/src/base/CommandLineOption.ml b/infer/src/base/CommandLineOption.ml index eeedf6016..45defd347 100644 --- a/infer/src/base/CommandLineOption.ml +++ b/infer/src/base/CommandLineOption.ml @@ -340,14 +340,9 @@ let curr_speclist : (Arg.key * Arg.spec * Arg.doc) list ref = ref [] let unknown_args_action = ref `Reject +let subcommand_actions = ref [] + let rev_anon_args = ref [] -let anon_fun arg = match !unknown_args_action with - | `Skip -> - () - | `Add -> - rev_anon_args := arg::!rev_anon_args - | `Reject -> - raise (Arg.Bad ("unexpected anonymous argument: " ^ arg)) (* keep track of the final parse action to drive the remainder of the program *) let final_parse_action = ref (Infer Driver) @@ -698,6 +693,20 @@ let select_parse_action ~usage ?parse_all action = final_parse_action := action; usage +let anon_fun arg = + match List.Assoc.find !subcommand_actions ~equal:String.equal arg with + | Some switch -> + switch () + | None -> + match !unknown_args_action with + | `Skip -> + () + | `Add -> + rev_anon_args := arg::!rev_anon_args + | `Reject -> + raise (Arg.Bad ("unexpected anonymous argument: " ^ arg)) + + let mk_rest_actions ?(parse_mode=Infer []) doc ~usage decode_action = let rest = ref [] in let spec = String (fun arg -> @@ -710,15 +719,19 @@ let mk_rest_actions ?(parse_mode=Infer []) doc ~usage decode_action = rest let mk_switch_parse_action - parse_action ~usage ?(deprecated=[]) ~long ?short ?parse_mode ?(meta="") doc = + parse_action ~usage ?(deprecated=[]) ~long ?(name=long) ?parse_mode ?(meta="") doc = let switch () = select_parse_action ~usage parse_action |> ignore in ignore( - mk ~deprecated ~long ?short ~default:() ?parse_mode ~meta doc + mk ~deprecated ~long ~default:() ?parse_mode ~meta doc ~default_to_string:(fun () -> "") ~decode_json:(string_json_decoder ~long) ~mk_setter:(fun _ _ -> switch ()) - ~mk_spec:(fun _ -> Unit switch)) + ~mk_spec:(fun _ -> Unit switch)); + let add_action opt = + let sub = (opt, switch) in + subcommand_actions := sub::!subcommand_actions in + add_action name let decode_inferconfig_to_argv path = let json = match Utils.read_json_file path with diff --git a/infer/src/base/CommandLineOption.mli b/infer/src/base/CommandLineOption.mli index ca3a3c35a..3bfbabfc9 100644 --- a/infer/src/base/CommandLineOption.mli +++ b/infer/src/base/CommandLineOption.mli @@ -144,9 +144,11 @@ val mk_rest_actions : -> string list ref -(** when the option is found on the command line, the current parse action is discarded and the - following arguments are parsed using [parse_action] *) -val mk_switch_parse_action : parse_action -> usage:string -> unit t +(** When the option is found on the command line, either as [--long] or [name], the current parse + action is discarded and the following arguments are parsed using [parse_action]. [name] defaults + to [long]. *) +val mk_switch_parse_action : parse_action -> usage:string -> ?deprecated:string list -> + long:string -> ?name:string -> ?parse_mode:section list parse -> ?meta:string -> string -> unit (** environment variable use to pass arguments from parent to child processes *) val args_env_var : string diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index e88531a67..77a252b90 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -402,8 +402,9 @@ let exe_usage = match current_exe with let anon_args = CLOpt.mk_anon () and () = - CLOpt.mk_switch_parse_action CLOpt.Differential ~usage:"infer --diff [options]" - ~long:"diff" "[experimental] compute differential report" + CLOpt.mk_switch_parse_action CLOpt.Differential ~usage:"infer reportdiff [options]" + ~deprecated:["-diff"] ~long:"reportdiff" + "difference (preexisting/introduced/fixed) between two infer reports" and abs_struct = CLOpt.mk_int ~deprecated:["absstruct"] ~long:"abs-struct" ~default:1 diff --git a/infer/tests/differential.make b/infer/tests/differential.make index c41fb0ace..4c05587a0 100644 --- a/infer/tests/differential.make +++ b/infer/tests/differential.make @@ -32,7 +32,7 @@ analyze: $(CURRENT_REPORT) $(PREVIOUS_REPORT) $(DIFFERENTIAL_REPORT): $(CURRENT_REPORT) $(PREVIOUS_REPORT) $(QUIET)$(call silent_on_success,Computing results difference in $(TEST_REL_DIR),\ - $(INFER_BIN) -o $(INFER_OUT) --project-root $(CURDIR) --diff \ + $(INFER_BIN) -o $(INFER_OUT) --project-root $(CURDIR) reportdiff \ --report-current $(CURRENT_REPORT) --report-previous $(PREVIOUS_REPORT) \ $(DIFFERENTIAL_ARGS))