[help] add --long-reset for list and optional options

Summary:
This makes the CLI more complete: before, it was often impossible to "go back"
once some options were passed, namely options produced by `mk_*_{list,opt}`.
Now these automatically create an accompanying `--<long>-reset` option that
resets the config variable to its default value.

Also unify our naming of `~meta` arguments:
- no more spaces in them (except one instance where it's a whole sentence)
- use `+foo` if `foo` can be specified multiple times

Reviewed By: dulmarod

Differential Revision: D5583187

fbshipit-source-id: a8c2567
master
Jules Villard 7 years ago committed by Facebook Github Bot
parent cdc54563d4
commit 6505fa694d

@ -161,12 +161,12 @@ $(b,infer) $(i,[options])|}
"Infer is a static analyzer. Given a collection of source files written in Java or in languages of the C family, and a command to build them, infer produces a list of potential issues."
; `P
"Infer consists of a collection of tools referenced in the $(i,SEE ALSO) section of this manual. See their respective manuals for more information about each."
; `P
"If a compilation command is specified via the $(b,--) option or one of the $(b,--clang-compilation-database[-escaped]) options, $(b,infer) behaves as $(b,infer-run)(1). Otherwise, $(b,infer) behaves as $(b,infer-analyze)(1)."
]
~options:
(`Prepend
[ `P
"If a compilation command is specified via the $(b,--) option or one of the $(b,--clang-compilation-database[-escaped]) options, $(b,infer) behaves as $(b,infer-run)(1). Otherwise, $(b,infer) behaves as $(b,infer-analyze)(1)."
; `P
"Every infer command accepts the arguments from all the other infer commands. The same option may affect and thus be list in the manual of several commands."
; `P
(Printf.sprintf
@ -175,6 +175,8 @@ $(b,infer) $(i,[options])|}
CLOpt.args_env_var Cmdliner.Manpage.s_environment Cmdliner.Manpage.s_files)
; `P
"Options can be specified inside an argument file $(i,file) by passing $(b,@)$(i,file) as argument. The format is one option per line, and enclosing single ' and double \" quotes are ignored."
; `P
"Options without a default value (e.g., $(b,--linter)) and options with list-like values (e.g., $(b,--Xbuck)) all have a corresponding $(b,--option-reset) flag that resets their values to nothing or the empty list, respectively. For instance, $(b,--Xbuck-reset) will cancel any previous $(b,--Xbuck) option passed to infer."
; `P
"See the manuals of individual infer commands for details about their supported options. The following is a list of all the supported options (see also $(b,--help-full) for options reserved for internal use)."
])

@ -316,11 +316,27 @@ let mk_set var value ?(deprecated= []) ~long ?short ?parse_mode ?in_help ?(meta=
~default_to_string:(fun () -> "") ~decode_json:(string_json_decoder ~long)
~mk_setter:(fun _ _ -> setter ()) ~mk_spec:(fun _ -> Unit setter ))
let mk_with_reset value ~reset_doc ?deprecated ~long ?parse_mode mk =
let var = mk () in
if not (String.equal "" long) then
(* Do not pass any ~in_help value so that the reset options only show up in --help-full and do
not clutter --help. *)
mk_set var value ?deprecated ~long:(long ^ "-reset") ?parse_mode reset_doc ;
var
let reset_doc_opt ~long = Printf.sprintf "Cancel the effect of $(b,%s)." (dashdash long)
let reset_doc_list ~long = Printf.sprintf "Set $(b,%s) to the empty list." (dashdash long)
let mk_option ?(default= None) ?(default_to_string= fun _ -> "") ~f ?(deprecated= []) ~long ?short
?parse_mode ?in_help ?(meta= "string") doc =
let mk () =
mk ~deprecated ~long ?short ~default ?parse_mode ?in_help ~meta doc ~default_to_string
~decode_json:(string_json_decoder ~long) ~mk_setter:(fun var str -> var := f str) ~mk_spec:
(fun set -> String set )
in
let reset_doc = reset_doc_opt ~long in
mk_with_reset None ~reset_doc ~long ?parse_mode mk
let mk_bool ?(deprecated_no= []) ?(default= false) ?(f= fun b -> b) ?(deprecated= []) ~long ?short
?parse_mode ?in_help ?(meta= "") doc =
@ -407,10 +423,15 @@ let mk_string_opt ?default ?(f= fun s -> s) ?(deprecated= []) ~long ?short ?pars
mk_option ~deprecated ~long ?short ~default ~default_to_string ~f ?parse_mode ?in_help ~meta doc
let mk_string_list ?(default= []) ?(f= fun s -> s) ?(deprecated= []) ~long ?short ?parse_mode
?in_help ?(meta= "+string") doc =
mk ~deprecated ~long ?short ~default ?parse_mode ?in_help ~meta doc
?in_help ?(meta= "string") doc =
let mk () =
mk ~deprecated ~long ?short ~default ?parse_mode ?in_help ~meta:("+" ^ meta) doc
~default_to_string:(String.concat ~sep:", ") ~mk_setter:(fun var str -> var := f str :: !var)
~decode_json:(list_json_decoder (string_json_decoder ~long)) ~mk_spec:(fun set -> String set )
~decode_json:(list_json_decoder (string_json_decoder ~long)) ~mk_spec:(fun set -> String set
)
in
let reset_doc = reset_doc_list ~long in
mk_with_reset [] ~reset_doc ~long ?parse_mode mk
let normalize_path_in_args_being_parsed ?(f= Fn.id) ~is_anon_arg str =
if Filename.is_relative str then
@ -439,20 +460,28 @@ let mk_path ~default ?(deprecated= []) ~long ?short ?parse_mode ?in_help ?(meta=
~default_to_string:(fun s -> s)
~default ~deprecated ~long ~short ~parse_mode ~in_help ~meta
let mk_path_opt ?default ?(deprecated= []) ~long ?short ?parse_mode ?in_help ?(meta= "path") =
let mk_path_opt ?default ?(deprecated= []) ~long ?short ?parse_mode ?in_help ?(meta= "path") doc =
let mk () =
mk_path_helper
~setter:(fun var x -> var := Some x)
~decode_json:(path_json_decoder ~long)
~default_to_string:(function Some s -> s | None -> "")
~default ~deprecated ~long ~short ~parse_mode ~in_help ~meta
~default ~deprecated ~long ~short ~parse_mode ~in_help ~meta doc
in
let reset_doc = reset_doc_opt ~long in
mk_with_reset None ~reset_doc ~long ?parse_mode mk
let mk_path_list ?(default= []) ?(deprecated= []) ~long ?short ?parse_mode ?in_help
?(meta= "+path") =
let mk_path_list ?(default= []) ?(deprecated= []) ~long ?short ?parse_mode ?in_help ?(meta= "path")
doc =
let mk () =
mk_path_helper
~setter:(fun var x -> var := x :: !var)
~decode_json:(list_json_decoder (path_json_decoder ~long))
~default_to_string:(String.concat ~sep:", ") ~default ~deprecated ~long ~short ~parse_mode
~in_help ~meta
~in_help ~meta:("+" ^ meta) doc
in
let reset_doc = reset_doc_list ~long in
mk_with_reset [] ~reset_doc ~long ?parse_mode mk
let mk_symbols_meta symbols =
let strings = List.map ~f:fst symbols in
@ -473,9 +502,13 @@ let mk_symbol_opt ~symbols ?(f= Fn.id) ?(deprecated= []) ~long ?short ?parse_mod
let strings = List.map ~f:fst symbols in
let of_string str = List.Assoc.find_exn ~equal:String.equal symbols str in
let meta = Option.value meta ~default:(mk_symbols_meta symbols) in
let mk () =
mk ~deprecated ~long ?short ~default:None ?parse_mode ?in_help ~meta doc
~default_to_string:(fun _ -> "") ~mk_setter:(fun var str -> var := Some (f (of_string str)))
~decode_json:(string_json_decoder ~long) ~mk_spec:(fun set -> Symbol (strings, set) )
in
let reset_doc = reset_doc_opt ~long in
mk_with_reset None ~reset_doc ~long ?parse_mode mk
let mk_symbol_seq ?(default= []) ~symbols ~eq ?(deprecated= []) ~long ?short ?parse_mode ?in_help
?meta doc =

@ -106,7 +106,10 @@ val mk_string_opt : ?default:string -> ?f:(string -> string) -> string option re
val mk_string_list : ?default:string list -> ?f:(string -> string) -> string list ref t
(** [mk_string_list] defines a [string list ref], initialized to [[]] unless overridden by
[~default]. Each argument of an occurrence of the option will be prepended to the list, so the
final value will be in the reverse order they appeared on the command line. *)
final value will be in the reverse order they appeared on the command line.
An option "--[long]-reset" is automatically created that resets the list to [] when found on the
command line. *)
val mk_path : default:string -> string ref t
(** like [mk_string] but will resolve the string into an absolute path so that children processes

@ -538,11 +538,11 @@ and ( analysis_blacklist_files_containing_options
, mk_filtering_options ~suffix:"blacklist-path-regex" ~deprecated_suffix:["blacklist"]
~help:
"blacklist the analysis of files whose relative path matches the specified OCaml-style regex (to whitelist: $(b,--<analyzer>-whitelist-path-regex))"
~meta:"path regex"
~meta:"path_regex"
, mk_filtering_options ~suffix:"whitelist-path-regex" ~deprecated_suffix:["whitelist"] ~help:""
~meta:"path regex"
~meta:"path_regex"
, mk_filtering_options ~suffix:"suppress-errors" ~deprecated_suffix:["suppress_errors"]
~help:"do not report a type of errors" ~meta:"error name" )
~help:"do not report a type of errors" ~meta:"error_name" )
and analysis_stops =
CLOpt.mk_bool ~deprecated:["analysis_stops"] ~long:"analysis-stops"
@ -792,11 +792,11 @@ and clang_frontend_action =
and clang_include_to_override_regex =
CLOpt.mk_string_opt ~long:"clang-include-to-override-regex"
~deprecated:["-clang-include-to-override"] ~meta:"dir OCaml regex"
~deprecated:["-clang-include-to-override"] ~meta:"dir_OCaml_regex"
"Use this option in the uncommon case where the normal compilation process overrides the location of internal compiler headers. This option should specify regular expression with the path to those headers so that infer can use its own clang internal headers instead."
and clang_ignore_regex =
CLOpt.mk_string_opt ~long:"clang-ignore-regex" ~meta:"dir OCaml regex"
CLOpt.mk_string_opt ~long:"clang-ignore-regex" ~meta:"dir_OCaml_regex"
"The files in this regex will be ignored in the compilation process and an empty file will be passed to clang instead. This is to be used with the buck flavour infer-capture-all to work around missing generated files."
and classpath = CLOpt.mk_string_opt ~long:"classpath" "Specify the Java classpath"
@ -1026,7 +1026,7 @@ and differential_filter_set =
~default:[`Introduced; `Fixed; `Preexisting]
and disable_checks =
CLOpt.mk_string_list ~deprecated:["disable_checks"] ~long:"disable-checks" ~meta:"error name"
CLOpt.mk_string_list ~deprecated:["disable_checks"] ~long:"disable-checks" ~meta:"error_name"
~in_help:CLOpt.([(Report, manual_generic)])
~default:
[ "ANALYSIS_STOPS"
@ -1061,7 +1061,7 @@ and dynamic_dispatch =
~symbols:[("none", `None); ("interface", `Interface); ("sound", `Sound); ("lazy", `Lazy)]
and enable_checks =
CLOpt.mk_string_list ~deprecated:["enable_checks"] ~long:"enable-checks" ~meta:"error name"
CLOpt.mk_string_list ~deprecated:["enable_checks"] ~long:"enable-checks" ~meta:"error_name"
"Show reports coming from this type of errors. This option has higher precedence than $(b,--disable-checks)"
and eradicate_condition_redundant =
@ -1184,7 +1184,7 @@ and iphoneos_target_sdk_version =
and iphoneos_target_sdk_version_skip_path =
CLOpt.mk_string_list ~long:"iphoneos-target-sdk-version-skip-path"
~in_help:CLOpt.([(Capture, manual_clang_linters)])
~meta:"path prefix OCaml regex"
~meta:"path_prefix_OCaml_regex"
"To be used together with iphoneos-target-sdk-version, to disable that flag in a particular path (can be specified multiple times)"
and issues_fields =
@ -1508,7 +1508,7 @@ and siof_safe_methods =
and skip_analysis_in_path =
CLOpt.mk_string_list ~deprecated:["-skip-clang-analysis-in-path"] ~long:"skip-analysis-in-path"
~in_help:CLOpt.([(Capture, manual_generic); (Run, manual_generic)])
~meta:"path prefix OCaml regex"
~meta:"path_prefix_OCaml_regex"
"Ignore files whose path matches the given prefix (can be specified multiple times)"
and skip_analysis_in_path_skips_compilation =
@ -1524,7 +1524,7 @@ and skip_duplicated_types =
and skip_translation_headers =
CLOpt.mk_string_list ~deprecated:["skip_translation_headers"] ~long:"skip-translation-headers"
~in_help:CLOpt.([(Capture, manual_clang)])
~meta:"path prefix" "Ignore headers whose path matches the given prefix"
~meta:"path_prefix" "Ignore headers whose path matches the given prefix"
and source_preview =
CLOpt.mk_bool ~long:"source-preview" ~default:true

Loading…
Cancel
Save