[subcommands] read subcommand args from .inferconfig and the env

Summary:
When parsing .inferconfig and the env var, allow all modes of infer. This
allows people to provide default values for options in .inferconfig. This
requires subcommands' options to be all distinct, but that's already the case.

Reviewed By: jberdine

Differential Revision: D4674672

fbshipit-source-id: 992b454
master
Jules Villard 8 years ago committed by Facebook Github Bot
parent 6f25eefc1d
commit 6125632af3

@ -72,18 +72,20 @@ type parse_action = section parse [@@deriving compare]
let equal_parse_action = [%compare.equal : parse_action ] let equal_parse_action = [%compare.equal : parse_action ]
type parse_tag = unit parse [@@deriving compare] (* NOTE: All variants must be also added to `all_parse_tags` below *)
type parse_tag = AllInferTags | OneTag of unit parse [@@deriving compare]
let equal_parse_tag = [%compare.equal : parse_tag ] let equal_parse_tag = [%compare.equal : parse_tag ]
let all_parse_tags = [ Differential; Infer (); Javac; NoParse ] let all_parse_tags = [
AllInferTags; OneTag Differential; OneTag (Infer ()); OneTag Javac; OneTag NoParse
]
(* NOTE: All variants must be also added to `all_parse_tags` below *) let to_parse_tag parse =
let to_parse_tag tag = match parse with
match tag with | Differential -> OneTag Differential
| Differential -> Differential | Infer _ -> OneTag (Infer ())
| Infer _ -> Infer () | Javac -> OneTag Javac
| Javac -> Javac | NoParse -> OneTag NoParse
| NoParse -> NoParse
let accept_unknown_args = function let accept_unknown_args = function
| Infer Print | Javac | NoParse -> true | Infer Print | Javac | NoParse -> true
@ -243,9 +245,14 @@ let infer_section_desc_lists = List.map ~f:(fun section -> (section, ref [])) al
(** add [desc] to the one relevant parse_tag_desc_lists for the purposes of parsing, and, in the (** add [desc] to the one relevant parse_tag_desc_lists for the purposes of parsing, and, in the
case of Infer, include [desc] in --help only for the relevant sections. *) case of Infer, include [desc] in --help only for the relevant sections. *)
let add parse_mode desc = let add parse_mode desc =
let tag = to_parse_tag parse_mode in let add_to_tag tag =
let full_desc_list = List.Assoc.find_exn parse_tag_desc_lists tag in let desc_list = List.Assoc.find_exn parse_tag_desc_lists tag in
full_desc_list := desc :: !full_desc_list ; desc_list := desc :: !desc_list in
(match parse_mode with
| Javac | NoParse -> ()
| Differential | Infer _ -> add_to_tag AllInferTags
);
add_to_tag (to_parse_tag parse_mode);
match parse_mode with match parse_mode with
| Differential | Javac | NoParse -> () | Differential | Javac | NoParse -> ()
| Infer sections -> | Infer sections ->
@ -554,7 +561,7 @@ let mk_rest ?(parse_mode=Infer []) doc =
add parse_mode {long = "--"; short = ""; meta = ""; doc; spec; decode_json = fun _ -> []} ; add parse_mode {long = "--"; short = ""; meta = ""; doc; spec; decode_json = fun _ -> []} ;
rest rest
let set_curr_speclist_for_parse_action ~incomplete ~usage parse_action = let set_curr_speclist_for_parse_action ~incomplete ~usage ?(parse_all=false) parse_action =
let full_speclist = ref [] in let full_speclist = ref [] in
let curr_usage status = let curr_usage status =
@ -565,7 +572,6 @@ let set_curr_speclist_for_parse_action ~incomplete ~usage parse_action =
Arg.usage (to_arg_speclist !full_speclist) usage ; Arg.usage (to_arg_speclist !full_speclist) usage ;
exit status exit status
in in
let parse_tag = to_parse_tag parse_action in
(* "-help" and "--help" are automatically recognized by Arg.parse, so we have to give them special (* "-help" and "--help" are automatically recognized by Arg.parse, so we have to give them special
treatment *) treatment *)
let add_or_suppress_help (speclist, (doc_width,left_width)) = let add_or_suppress_help (speclist, (doc_width,left_width)) =
@ -613,11 +619,12 @@ let set_curr_speclist_for_parse_action ~incomplete ~usage parse_action =
let add_to_curr_speclist ?(add_help=false) ?header parse_action = let add_to_curr_speclist ?(add_help=false) ?header parse_action =
let mk_header_spec heading = let mk_header_spec heading =
("", Unit (fun () -> ()), "\n## " ^ heading ^ "\n") in ("", Unit (fun () -> ()), "\n## " ^ heading ^ "\n") in
let exe_descs = let exe_descs = match parse_all, parse_action with
match parse_action with | true, _ ->
| Infer section -> List.Assoc.find_exn ~equal:equal_parse_tag parse_tag_desc_lists AllInferTags
| false, Infer section ->
List.Assoc.find_exn ~equal:equal_section infer_section_desc_lists section List.Assoc.find_exn ~equal:equal_section infer_section_desc_lists section
| Differential | Javac | NoParse -> | false, (Differential | Javac | NoParse) ->
to_parse_tag parse_action to_parse_tag parse_action
|> List.Assoc.find_exn ~equal:equal_parse_tag parse_tag_desc_lists in |> List.Assoc.find_exn ~equal:equal_parse_tag parse_tag_desc_lists in
let (exe_speclist, widths) = normalize !exe_descs in let (exe_speclist, widths) = normalize !exe_descs in
@ -654,14 +661,16 @@ let set_curr_speclist_for_parse_action ~incomplete ~usage parse_action =
; ;
assert( check_no_duplicates !curr_speclist ) assert( check_no_duplicates !curr_speclist )
; ;
let full_desc_list = List.Assoc.find_exn ~equal:equal_parse_tag parse_tag_desc_lists parse_tag in let full_desc_list =
let parse_tag = if parse_all then AllInferTags else to_parse_tag parse_action in
List.Assoc.find_exn ~equal:equal_parse_tag parse_tag_desc_lists parse_tag in
full_speclist := add_or_suppress_help (normalize !full_desc_list) full_speclist := add_or_suppress_help (normalize !full_desc_list)
; ;
curr_usage curr_usage
let select_parse_action ~incomplete ~usage action = let select_parse_action ~incomplete ~usage ?parse_all action =
let usage = set_curr_speclist_for_parse_action ~incomplete ~usage action in let usage = set_curr_speclist_for_parse_action ~incomplete ~usage ?parse_all action in
unknown_args_action := if accept_unknown_args action then `Add else `Reject; unknown_args_action := if accept_unknown_args action then `Add else `Reject;
final_parse_action := action; final_parse_action := action;
usage usage
@ -694,7 +703,7 @@ let decode_inferconfig_to_argv path =
| Error msg -> | Error msg ->
warnf "WARNING: Could not read or parse Infer config in %s:@\n%s@." path msg ; warnf "WARNING: Could not read or parse Infer config in %s:@\n%s@." path msg ;
`Assoc [] in `Assoc [] in
let desc_list = List.Assoc.find_exn ~equal:equal_parse_tag parse_tag_desc_lists (Infer ()) in let desc_list = List.Assoc.find_exn ~equal:equal_parse_tag parse_tag_desc_lists AllInferTags in
let json_config = YBU.to_assoc json in let json_config = YBU.to_assoc json in
let one_config_item result (key, json_val) = let one_config_item result (key, json_val) =
try try
@ -749,11 +758,11 @@ let extra_env_args = ref []
let extend_env_args args = let extend_env_args args =
extra_env_args := List.rev_append args !extra_env_args extra_env_args := List.rev_append args !extra_env_args
let parse_args ~incomplete ~usage action args = let parse_args ~incomplete ~usage ?parse_all action args =
let exe_name = Sys.executable_name in let exe_name = Sys.executable_name in
args_to_parse := Array.of_list (exe_name :: args); args_to_parse := Array.of_list (exe_name :: args);
arg_being_parsed := 0; arg_being_parsed := 0;
let curr_usage = select_parse_action ~incomplete ~usage action in let curr_usage = select_parse_action ~incomplete ~usage ?parse_all action in
(* tests if msg indicates an unknown option, as opposed to a known option with bad argument *) (* tests if msg indicates an unknown option, as opposed to a known option with bad argument *)
let is_unknown msg = String.is_substring msg ~substring:": unknown option" in let is_unknown msg = String.is_substring msg ~substring:": unknown option" in
let rec parse_loop () = let rec parse_loop () =
@ -794,10 +803,10 @@ let parse ?(incomplete=false) ?config_file ~usage action =
else !args_to_export ^ String.of_char env_var_sep ^ encode_argv_to_env args in else !args_to_export ^ String.of_char env_var_sep ^ encode_argv_to_env args in
args_to_export := arg_string in args_to_export := arg_string in
(* read .inferconfig first, then env vars, then command-line options *) (* read .inferconfig first, then env vars, then command-line options *)
parse_args ~incomplete ~usage (Infer Driver) inferconfig_args |> ignore; parse_args ~incomplete ~usage ~parse_all:true (Infer Driver) inferconfig_args |> ignore;
(* NOTE: do not add the contents of .inferconfig to INFER_ARGS. This helps avoid hitting the (* NOTE: do not add the contents of .inferconfig to INFER_ARGS. This helps avoid hitting the
command line size limit. *) command line size limit. *)
parse_args ~incomplete ~usage (Infer Driver) env_args |> ignore; parse_args ~incomplete ~usage ~parse_all:true (Infer Driver) env_args |> ignore;
if not incomplete then add_parsed_args_to_args_to_export (); if not incomplete then add_parsed_args_to_args_to_export ();
let curr_usage = let curr_usage =
let cl_args = match Array.to_list Sys.argv with _ :: tl -> tl | [] -> [] in let cl_args = match Array.to_list Sys.argv with _ :: tl -> tl | [] -> [] in

@ -1,5 +1,6 @@
{ {
"eradicate-whitelist-path-regex": [ "eradicate-whitelist-path-regex": [
"src/com" "src/com"
] ],
"resolve-infer-eradicate-conflict": true
} }

@ -8,19 +8,19 @@
# E2E test involving the resolve_infer_eradicate_conflict filter # E2E test involving the resolve_infer_eradicate_conflict filter
TESTS_DIR = ../.. TESTS_DIR = ../..
DIFFERENTIAL_ARGS = --resolve-infer-eradicate-conflict DIFFERENTIAL_ARGS =
CLEAN_EXTRA = src/com/example/Diff*.java src/Diff*.java *.class com/ CLEAN_EXTRA = src/com/example/Diff*.java src/Diff*.java *.class com/
include ../../differential.make include ../../differential.make
$(CURRENT_REPORT): $(CURRENT_REPORT): .inferconfig
cp src/com/example/DiffExample.java.current src/com/example/DiffExample.java cp src/com/example/DiffExample.java.current src/com/example/DiffExample.java
cp src/DiffExampleTwo.java.current src/DiffExampleTwo.java cp src/DiffExampleTwo.java.current src/DiffExampleTwo.java
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) \ $(INFER_BIN) \
-o $(CURRENT_DIR) -- javac src/com/example/DiffExample.java src/DiffExampleTwo.java) -o $(CURRENT_DIR) -- javac src/com/example/DiffExample.java src/DiffExampleTwo.java)
$(PREVIOUS_REPORT): $(PREVIOUS_REPORT): .inferconfig
cp src/com/example/DiffExample.java.previous src/com/example/DiffExample.java cp src/com/example/DiffExample.java.previous src/com/example/DiffExample.java
$(call silent_on_success,\ $(call silent_on_success,\
$(INFER_BIN) -o $(PREVIOUS_DIR) -- javac src/com/example/DiffExample.java) $(INFER_BIN) -o $(PREVIOUS_DIR) -- javac src/com/example/DiffExample.java)

Loading…
Cancel
Save