From 0475e79d0ecf3aedcdfa1070a0046aceaa3034b8 Mon Sep 17 00:00:00 2001 From: Nikos Gorogiannis Date: Wed, 5 Aug 2020 07:12:55 -0700 Subject: [PATCH] [buck-java-flavor] filter out targets with no java sources Summary: As per title. Reviewed By: artempyanykh Differential Revision: D22235493 fbshipit-source-id: 6746cda6d --- infer/src/integration/Buck.ml | 117 ++++++++++++++++++++++++++- infer/src/integration/BuckGenrule.ml | 2 +- 2 files changed, 114 insertions(+), 5 deletions(-) diff --git a/infer/src/integration/Buck.ml b/infer/src/integration/Buck.ml index 15b26eb0b..0ab232da4 100644 --- a/infer/src/integration/Buck.ml +++ b/infer/src/integration/Buck.ml @@ -89,6 +89,56 @@ module Target = struct add_flavor_internal target "infer-capture-all" end +let config = + let clang_path = + List.fold ["clang"; "install"; "bin"; "clang"] ~init:Config.fcp_dir ~f:Filename.concat + in + let get_java_genrule_config () = + ["infer.version=" ^ Version.versionString; "infer.mode=capture"] + in + let get_java_flavor_config () = + if Config.buck_java_flavor_suppress_config then [] + else + [ "infer_java.version=" ^ Version.versionString + ; Printf.sprintf "infer_java.binary=%s/infer" Config.bin_dir ] + in + let get_flavors_config () = + [ "client.id=infer.clang" + ; Printf.sprintf "*//infer.infer_bin=%s" Config.bin_dir + ; Printf.sprintf "*//infer.clang_compiler=%s" clang_path + ; Printf.sprintf "*//infer.clang_plugin=%s" Config.clang_plugin_path + ; "*//cxx.pch_enabled=false" + ; (* Infer doesn't support C++ modules yet (T35656509) *) + "*//cxx.modules_default=false" + ; "*//cxx.modules=false" ] + @ ( match Config.xcode_developer_dir with + | Some d -> + [Printf.sprintf "apple.xcode_developer_dir=%s" d] + | None -> + [] ) + @ + if List.is_empty Config.buck_blacklist then [] + else + [ Printf.sprintf "*//infer.blacklist_regex=(%s)" + (String.concat ~sep:")|(" Config.buck_blacklist) ] + in + fun buck_mode -> + let args = + match (buck_mode : BuckMode.t) with + | JavaGenruleMaster -> + get_java_genrule_config () + | JavaFlavor -> + get_java_flavor_config () + | ClangFlavors -> + get_flavors_config () + | CombinedGenrule -> + get_java_genrule_config () @ get_flavors_config () + | ClangCompilationDB _ -> + [] + in + List.fold args ~init:[] ~f:(fun acc f -> "--config" :: f :: acc) + + let parse_target_string = let alias_target_regexp = Str.regexp "^[^/:]+\\(#.*\\)?$" in let pattern_target_regexp = Str.regexp "^[^/]*//\\(\\.\\.\\.\\|.*\\(:\\|/\\.\\.\\.\\)\\)$" in @@ -162,12 +212,71 @@ module Query = struct F.fprintf fmt "attrfilter(labels, %s, %a)" label pp expr - let exec ?(buck_config = []) expr = + (* example query json output + [ + { + "//example/foo:bar" : { + "srcs" : [ "example/foo/bar.cc", "example/foo/lib/lib.cc" ] + } + "//example/foo:main" : {} + } + ] + *) + let parse_query_output ?buck_mode output = + let get_target_srcs_assoc_list json = + match json with + | `Assoc fields -> + fields + | _ -> + L.internal_error "Could not parse target json: %s@." (Yojson.Basic.to_string json) ; + [] + in + let get_json_field fieldname = function + | `Assoc fields -> + List.Assoc.find fields ~equal:String.equal fieldname + | _ -> + None + in + let is_valid_source source_path_json = + match source_path_json with + | `String source_path -> + String.is_suffix ~suffix:".java" source_path + && not (String.is_suffix ~suffix:"MetagenRoot.java" source_path) + | _ -> + L.internal_error "Could not parse source path json: %s@." + (Yojson.Basic.to_string source_path_json) ; + false + in + let process_target acc (target, json) = + match get_json_field "srcs" json with + | Some (`List srcs) when List.exists srcs ~f:is_valid_source -> + target :: acc + | _ -> + acc + in + match (buck_mode : BuckMode.t option) with + | Some JavaFlavor -> + String.concat output |> Yojson.Basic.from_string |> get_target_srcs_assoc_list + |> List.fold ~init:[] ~f:process_target + | _ -> + output + + + let exec ?buck_mode expr = let query = F.asprintf "%a" pp expr in + let buck_config = Option.value_map buck_mode ~default:[] ~f:config in + let buck_output_options = + match (buck_mode : BuckMode.t option) with + | Some JavaFlavor -> + ["--output-format"; "json"; "--output-attribute"; "srcs"] + | _ -> + [] + in let cmd = - ("buck" :: "query" :: buck_config) @ List.rev_append Config.buck_build_args_no_inline [query] + ("buck" :: "query" :: buck_config) + @ List.rev_append Config.buck_build_args_no_inline (query :: buck_output_options) in - wrap_buck_call ~label:"query" cmd + wrap_buck_call ~label:"query" cmd |> parse_query_output ?buck_mode end let accepted_buck_commands = ["build"] @@ -274,7 +383,7 @@ let resolve_pattern_targets (buck_mode : BuckMode.t) targets = |> ( if BuckMode.is_java_genrule_master_or_combined buck_mode then Query.label_filter ~label:infer_enabled_label else Fn.id ) - |> Query.exec ~buck_config:(config buck_mode) + |> Query.exec ~buck_mode |> if BuckMode.is_java_genrule_master_or_combined buck_mode then List.rev_map ~f:(fun s -> s ^ genrule_suffix) diff --git a/infer/src/integration/BuckGenrule.ml b/infer/src/integration/BuckGenrule.ml index bc02caf7b..6373baea3 100644 --- a/infer/src/integration/BuckGenrule.ml +++ b/infer/src/integration/BuckGenrule.ml @@ -66,7 +66,7 @@ let read_and_parse_report build_report = in match path_opt with | None -> - L.internal_error "Could not parse target json: %s" (Yojson.Basic.to_string json) ; + L.internal_error "Could not parse target json: %s@." (Yojson.Basic.to_string json) ; None | Some path -> Some (target, path)