[buck][java] remove genrule integration and combined mode

Summary:
Now that the buck java flavour is fully deployed, the genrule-based integrations for java can be removed. We also remove the combined (clang+java) integration as this will be reimplemented using flavours in the future.

Also, remove a bunch of deprecated arguments linked to these integrations.

Reviewed By: jvillard

Differential Revision: D26104384

fbshipit-source-id: 6b0059407
master
Nikos Gorogiannis 4 years ago committed by Facebook GitHub Bot
parent e04f0a0ffa
commit 7e4dc9477e

@ -183,7 +183,7 @@ endif
ifneq ($(BUCK),no)
BUILD_SYSTEMS_TESTS += genrulecapture buck_java_flavor
BUILD_SYSTEMS_TESTS += buck_java_flavor
endif
ifneq ($(MVN),no)
BUILD_SYSTEMS_TESTS += mvn

@ -133,10 +133,6 @@ BUCK OPTIONS
Activates: Buck integration for clang-based targets
(C/C++/Objective-C/Objective-C++). (Conversely: --no-buck-clang)
--buck-combined
Activates: Buck integration for clang-based and Java targets.
(Conversely: --no-buck-combined)
--buck-compilation-database { no-deps | deps }
Buck integration using the compilation database, with or without
dependencies. Only includes clang targets, as per Buck's
@ -146,10 +142,6 @@ BUCK OPTIONS
Depth of dependencies used by the --buck-compilation-database deps
option. By default, all recursive dependencies are captured.
--buck-java
Activates: Buck integration for Java targets. (Conversely:
--no-buck-java)
--buck-java-flavor
Activates: Buck integration for Java which uses the buck flavor
#infer-java-capture instead of genrules like buck-java.

@ -140,10 +140,6 @@ OPTIONS
(C/C++/Objective-C/Objective-C++). (Conversely: --no-buck-clang)
See also infer-capture(1).
--buck-combined
Activates: Buck integration for clang-based and Java targets.
(Conversely: --no-buck-combined) See also infer-capture(1).
--buck-compilation-database { no-deps | deps }
Buck integration using the compilation database, with or without
dependencies. Only includes clang targets, as per Buck's
@ -154,10 +150,6 @@ OPTIONS
option. By default, all recursive dependencies are captured.
See also infer-capture(1).
--buck-java
Activates: Buck integration for Java targets. (Conversely:
--no-buck-java) See also infer-capture(1).
--buck-java-flavor
Activates: Buck integration for Java which uses the buck flavor
#infer-java-capture instead of genrules like buck-java.

@ -140,10 +140,6 @@ OPTIONS
(C/C++/Objective-C/Objective-C++). (Conversely: --no-buck-clang)
See also infer-capture(1).
--buck-combined
Activates: Buck integration for clang-based and Java targets.
(Conversely: --no-buck-combined) See also infer-capture(1).
--buck-compilation-database { no-deps | deps }
Buck integration using the compilation database, with or without
dependencies. Only includes clang targets, as per Buck's
@ -154,10 +150,6 @@ OPTIONS
option. By default, all recursive dependencies are captured.
See also infer-capture(1).
--buck-java
Activates: Buck integration for Java targets. (Conversely:
--no-buck-java) See also infer-capture(1).
--buck-java-flavor
Activates: Buck integration for Java which uses the buck flavor
#infer-java-capture instead of genrules like buck-java.

@ -20,29 +20,13 @@ let pp_clang_compilation_db_deps fmt = function
F.pp_print_string fmt "DepsAllDepths"
type t =
| CombinedGenrule
| ClangFlavors
| ClangCompilationDB of clang_compilation_db_deps
| JavaFlavor
| JavaGenruleMaster
let is_java_genrule_master_or_combined = function
| JavaGenruleMaster | CombinedGenrule ->
true
| ClangFlavors | ClangCompilationDB _ | JavaFlavor ->
false
type t = ClangFlavors | ClangCompilationDB of clang_compilation_db_deps | JavaFlavor
let is_clang_compilation_db = function
| ClangCompilationDB _ ->
true
| ClangFlavors | JavaGenruleMaster | CombinedGenrule | JavaFlavor ->
| ClangFlavors | JavaFlavor ->
false
let is_clang_flavors = function
| ClangFlavors ->
true
| ClangCompilationDB _ | JavaGenruleMaster | CombinedGenrule | JavaFlavor ->
false
let is_clang_flavors = function ClangFlavors -> true | ClangCompilationDB _ | JavaFlavor -> false

@ -13,14 +13,7 @@ type clang_compilation_db_deps = NoDependencies | DepsUpToDepth of int | DepsAll
val pp_clang_compilation_db_deps : F.formatter -> clang_compilation_db_deps -> unit
type t =
| CombinedGenrule
| ClangFlavors
| ClangCompilationDB of clang_compilation_db_deps
| JavaFlavor
| JavaGenruleMaster
val is_java_genrule_master_or_combined : t -> bool
type t = ClangFlavors | ClangCompilationDB of clang_compilation_db_deps | JavaFlavor
val is_clang_compilation_db : t -> bool

@ -730,20 +730,6 @@ and buck_mode =
~f:(set_mode `ClangFlavors)
"Buck integration for clang-based targets (C/C++/Objective-C/Objective-C++)."
|> ignore ;
CLOpt.mk_bool ~long:"buck-java"
~deprecated:
[ "-genrule-master-mode"
; "-no-genrule-master-mode"
(* --no-genrule-master-mode was used in the past to enable a now-defunct Java integration,
so both --genrule-master-mode and --no-genrule-master-mode enable the Java
integration... sorry about that. *)
; "-no-flavors"
(* --no-flavors was used in the past to enable the Java integration in some cases, let's
keep it that way for compatibility for now *) ]
~in_help:InferCommand.[(Capture, manual_buck)]
~f:(set_mode `Java)
"Buck integration for Java targets."
|> ignore ;
CLOpt.mk_symbol_opt ~long:"buck-compilation-database" ~deprecated:["-use-compilation-database"]
~in_help:InferCommand.[(Capture, manual_buck)]
~f:(fun s ->
@ -753,11 +739,6 @@ and buck_mode =
clang targets, as per Buck's $(i,#compilation-database) flavor."
~symbols:[("no-deps", `NoDeps); ("deps", `DepsTmp)]
|> ignore ;
CLOpt.mk_bool ~long:"buck-combined"
~in_help:InferCommand.[(Capture, manual_buck)]
~f:(set_mode `CombinedGenrule)
"Buck integration for clang-based and Java targets."
|> ignore ;
CLOpt.mk_bool ~long:"buck-java-flavor"
~in_help:InferCommand.[(Capture, manual_buck)]
~f:(set_mode `JavaFlavor)
@ -2776,16 +2757,12 @@ and buck_mode : BuckMode.t option =
None
| `ClangFlavors, _ ->
Some ClangFlavors
| `Java, _ ->
Some JavaGenruleMaster
| `ClangCompilationDB `NoDeps, _ ->
Some (ClangCompilationDB NoDependencies)
| `ClangCompilationDB `DepsTmp, None ->
Some (ClangCompilationDB DepsAllDepths)
| `ClangCompilationDB `DepsTmp, Some depth ->
Some (ClangCompilationDB (DepsUpToDepth depth))
| `CombinedGenrule, _ ->
Some CombinedGenrule
| `JavaFlavor, _ ->
Some JavaFlavor

@ -114,7 +114,7 @@ module Target = struct
match (mode, command) with
| ClangCompilationDB _, _ ->
add_flavor_internal target "compilation-database"
| ClangFlavors, Compile | JavaGenruleMaster, _ | CombinedGenrule, _ ->
| ClangFlavors, Compile ->
target
| JavaFlavor, _ ->
add_flavor_internal target "infer-java-capture"
@ -126,9 +126,6 @@ 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
@ -158,14 +155,10 @@ let config =
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
@ -201,7 +194,6 @@ module Query = struct
| Set of string list
| Target of string
| Union of expr list
| Labelfilter of {label: string; expr: expr}
exception NotATarget
@ -226,8 +218,6 @@ module Query = struct
Union exprs
let label_filter ~label expr = Labelfilter {label; expr}
let rec pp fmt = function
| Target s ->
F.pp_print_string fmt s
@ -241,8 +231,6 @@ module Query = struct
F.fprintf fmt "set(%a)" (Pp.seq F.pp_print_string) sl
| Union exprs ->
Pp.seq ~sep:" + " pp fmt exprs
| Labelfilter {label; expr} ->
F.fprintf fmt "attrfilter(labels, %s, %a)" label pp expr
(* example query json output
@ -335,70 +323,12 @@ let parameters_with_argument =
let get_accepted_buck_kinds_pattern (mode : BuckMode.t) =
match mode with
| CombinedGenrule ->
"^(android|apple|cxx|java)_(binary|library)$"
| ClangCompilationDB _ ->
"^(apple|cxx)_(binary|library|test)$"
| ClangFlavors ->
"^(apple|cxx)_(binary|library)$"
| JavaGenruleMaster | JavaFlavor ->
"^(java|android)_library$"
(** for genrule_master_mode, this is the label expected on the capture genrules *)
let infer_enabled_label = "infer_enabled"
(** for genrule_master_mode, this is the target name suffix for the capture genrules *)
let genrule_suffix = "_infer"
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)
"^(java|android)_library$"
let resolve_pattern_targets (buck_mode : BuckMode.t) targets =
@ -406,19 +336,12 @@ let resolve_pattern_targets (buck_mode : BuckMode.t) targets =
|> ( match buck_mode with
| ClangFlavors | ClangCompilationDB NoDependencies ->
Fn.id
| CombinedGenrule | ClangCompilationDB DepsAllDepths | JavaGenruleMaster | JavaFlavor ->
| ClangCompilationDB DepsAllDepths | JavaFlavor ->
Query.deps None
| ClangCompilationDB (DepsUpToDepth depth) ->
Query.deps (Some depth) )
|> Query.kind ~pattern:(get_accepted_buck_kinds_pattern buck_mode)
|> ( if BuckMode.is_java_genrule_master_or_combined buck_mode then
Query.label_filter ~label:infer_enabled_label
else Fn.id )
|> Query.exec ~buck_mode
|>
if BuckMode.is_java_genrule_master_or_combined buck_mode then
List.rev_map ~f:(fun s -> s ^ genrule_suffix)
else Fn.id
type parsed_args =
@ -497,7 +420,7 @@ let parse_command_and_targets (buck_mode : BuckMode.t) original_buck_args =
match (buck_mode, parsed_args) with
| ClangFlavors, {pattern_targets= []; alias_targets= []; normal_targets} ->
normal_targets
| ( (ClangFlavors | CombinedGenrule | JavaGenruleMaster | ClangCompilationDB _ | JavaFlavor)
| ( (ClangFlavors | ClangCompilationDB _ | JavaFlavor)
, {pattern_targets; alias_targets; normal_targets} ) ->
pattern_targets |> List.rev_append alias_targets |> List.rev_append normal_targets
|> resolve_pattern_targets buck_mode

@ -1,185 +0,0 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
module F = Format
module L = Logging
(* example build report json output
[
{
"success" : true,
"results" : {
"//annotations:annotations_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/annotations/annotations_infer/infer_out"
},
"//module2:module2_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/module2/module2_infer/infer_out"
},
"//module1:module1_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/module1/module1_infer/infer_out"
},
"//module3:module1_infer" : {
"success" : "SUCCESS",
"type" : "BUILT_LOCALLY",
"outputs" : {
"DEFAULT" : [ "buck-out/gen/module1/module3_infer/infer_out" ]
}
}
},
"failures" : { }
}%
]
*)
(** Read the build report json file buck produced, and parse into a list of pairs
[(target, output-path)]. NB contrary to what buck documentation says, the output path is always
present even when the target is locally cached. *)
let read_and_parse_report build_report =
let get_json_field fieldname = function
| `Assoc fields ->
List.Assoc.find fields ~equal:String.equal fieldname
| _ ->
None
in
let parse_target (target, json) =
let path_opt =
match get_json_field "output" json with
| Some (`String str) ->
Some str
| _ -> (
match get_json_field "outputs" json |> Option.bind ~f:(get_json_field "DEFAULT") with
| Some (`List [`String str]) ->
Some str
| _ ->
None )
in
match path_opt with
| None ->
L.internal_error "Could not parse target json: %s@." (Yojson.Basic.to_string json) ;
None
| Some path ->
Some (target, path)
in
let parse_results = function
| `Assoc results ->
(* NB this will simply skip unparseable targets *)
List.filter_map results ~f:parse_target |> Option.some
| _ ->
None
in
Yojson.Basic.from_file build_report |> get_json_field "results" |> Option.bind ~f:parse_results
(** Function for processing paths in a buck build report and generating an [infer-deps.txt] file.
Given a pair [(buck_target, output_path)],
- if [output_path] contains a capture DB, then generate the appropriate deps line;
- if [output_path] contains an [infer-deps.txt] file, expand and inline it;
- if [output_path] is a dummy target used in the combined genrule integration for clang targets,
read its contents, parse them as an output directory path and apply the above two tests to
that *)
let expand_target acc (target, target_path) =
let expand_dir acc (target, target_path) =
(* invariant: [target_path] is absolute *)
let db_file = ResultsDirEntryName.get_path ~results_dir:target_path CaptureDB in
match Sys.file_exists db_file with
| `Yes ->
(* there is a capture DB at this path, so terminate expansion and generate deps line *)
let line = Printf.sprintf "%s\t-\t%s" target target_path in
line :: acc
| `No | `Unknown -> (
(* no capture DB was found, so look for, and inline, an [infer-deps.txt] file *)
let infer_deps =
ResultsDirEntryName.get_path ~results_dir:target_path CaptureDependencies
in
match Sys.file_exists infer_deps with
| `Yes ->
Utils.with_file_in infer_deps
~f:(In_channel.fold_lines ~init:acc ~f:(fun acc line -> line :: acc))
| `No | `Unknown ->
L.internal_error "No capture DB or infer-deps file in %s@." target_path ;
acc )
in
let target_path =
if Filename.is_absolute target_path then target_path else Config.project_root ^/ target_path
in
match Sys.is_directory target_path with
| `Yes ->
(* output path is directory, so should contain either a capture DB or an [infer-deps.txt] file *)
expand_dir acc (target, target_path)
| `No | `Unknown -> (
(* output path is not a directory, so assume it's an intermediate genrule output containing the
output path of the underlying capture target *)
match Utils.read_file target_path with
| Ok [new_target_path] ->
expand_dir acc (target, new_target_path)
| Ok _ ->
L.internal_error "Couldn't parse intermediate deps file %s@." target_path ;
acc
| Error error ->
L.internal_error "Error %s@\nCouldn't read intermediate deps file %s@." error target_path ;
acc )
let infer_deps_of_build_report build_report =
match read_and_parse_report build_report with
| None ->
L.die InternalError "Couldn't parse buck build report: %s@." build_report
| Some target_path_list ->
let infer_deps_lines =
List.fold target_path_list ~init:[] ~f:expand_target
|> List.dedup_and_sort ~compare:String.compare
in
let infer_deps = ResultsDir.get_path CaptureDependencies in
Utils.with_file_out infer_deps ~f:(fun out_channel ->
Out_channel.output_lines out_channel infer_deps_lines )
let run_buck_capture cmd =
let path_var = "PATH" in
let new_path =
Sys.getenv path_var
|> Option.value_map ~default:Config.bin_dir ~f:(fun old_path -> Config.bin_dir ^ ":" ^ old_path)
in
let extend_env = [(path_var, new_path)] in
Buck.wrap_buck_call ~extend_env ~label:"build" cmd |> ignore
let capture buck_mode build_cmd =
let prog, buck_cmd = (List.hd_exn build_cmd, List.tl_exn build_cmd) in
L.progress "Querying buck for genrule capture targets...@." ;
let time0 = Mtime_clock.counter () in
let command, args, targets = Buck.parse_command_and_targets buck_mode buck_cmd in
L.progress "Found %d genrule capture targets in %a.@." (List.length targets) Mtime.Span.pp
(Mtime_clock.count time0) ;
let all_args = List.rev_append args targets in
let build_report_file =
Filename.temp_file ~in_dir:(ResultsDir.get_path Temporary) "buck_build_report" ".json"
in
let updated_buck_cmd =
(* make buck tell us where in buck-out are the capture directories for merging *)
(prog :: command :: "--build-report" :: build_report_file :: Buck.config buck_mode)
@ Config.buck_build_args_no_inline
@ Buck.store_args_in_file ~identifier:"genrule_build" all_args
in
L.(debug Capture Quiet)
"Processed buck command '%a'@." (Pp.seq F.pp_print_string) updated_buck_cmd ;
if List.is_empty targets then L.external_warning "WARNING: found no buck targets to analyze.@."
else
let time0 = Mtime_clock.counter () in
run_buck_capture updated_buck_cmd ;
infer_deps_of_build_report build_report_file ;
L.progress "Genrule capture took %a.@." Mtime.Span.pp (Mtime_clock.count time0) ;
ResultsDir.RunState.set_merge_capture true ;
()

@ -1,14 +0,0 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
val infer_deps_of_build_report : string -> unit
(** parse a buck build report and construct resulting [infer-deps.txt] *)
val capture : BuckMode.t -> string list -> unit
(** do genrule capture with the given buck command line *)

@ -9,6 +9,143 @@ open! IStd
module F = Format
module L = Logging
(* example build report json output
[
{
"success" : true,
"results" : {
"//annotations:annotations_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/annotations/annotations_infer/infer_out"
},
"//module2:module2_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/module2/module2_infer/infer_out"
},
"//module1:module1_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/module1/module1_infer/infer_out"
},
"//module3:module1_infer" : {
"success" : "SUCCESS",
"type" : "BUILT_LOCALLY",
"outputs" : {
"DEFAULT" : [ "buck-out/gen/module1/module3_infer/infer_out" ]
}
}
},
"failures" : { }
}%
]
*)
(** Read the build report json file buck produced, and parse into a list of pairs
[(target, output-path)]. NB contrary to what buck documentation says, the output path is always
present even when the target is locally cached. *)
let read_and_parse_report build_report =
let get_json_field fieldname = function
| `Assoc fields ->
List.Assoc.find fields ~equal:String.equal fieldname
| _ ->
None
in
let parse_target (target, json) =
let path_opt =
match get_json_field "output" json with
| Some (`String str) ->
Some str
| _ -> (
match get_json_field "outputs" json |> Option.bind ~f:(get_json_field "DEFAULT") with
| Some (`List [`String str]) ->
Some str
| _ ->
None )
in
match path_opt with
| None ->
L.internal_error "Could not parse target json: %s@." (Yojson.Basic.to_string json) ;
None
| Some path ->
Some (target, path)
in
let parse_results = function
| `Assoc results ->
(* NB this will simply skip unparseable targets *)
List.filter_map results ~f:parse_target |> Option.some
| _ ->
None
in
Yojson.Basic.from_file build_report |> get_json_field "results" |> Option.bind ~f:parse_results
(** Function for processing paths in a buck build report and generating an [infer-deps.txt] file.
Given a pair [(buck_target, output_path)],
- if [output_path] contains a capture DB, then generate the appropriate deps line;
- if [output_path] contains an [infer-deps.txt] file, expand and inline it;
- if [output_path] is a dummy target used in the combined genrule integration for clang targets,
read its contents, parse them as an output directory path and apply the above two tests to
that *)
let expand_target acc (target, target_path) =
let expand_dir acc (target, target_path) =
(* invariant: [target_path] is absolute *)
let db_file = ResultsDirEntryName.get_path ~results_dir:target_path CaptureDB in
match Sys.file_exists db_file with
| `Yes ->
(* there is a capture DB at this path, so terminate expansion and generate deps line *)
let line = Printf.sprintf "%s\t-\t%s" target target_path in
line :: acc
| `No | `Unknown -> (
(* no capture DB was found, so look for, and inline, an [infer-deps.txt] file *)
let infer_deps =
ResultsDirEntryName.get_path ~results_dir:target_path CaptureDependencies
in
match Sys.file_exists infer_deps with
| `Yes ->
Utils.with_file_in infer_deps
~f:(In_channel.fold_lines ~init:acc ~f:(fun acc line -> line :: acc))
| `No | `Unknown ->
L.internal_error "No capture DB or infer-deps file in %s@." target_path ;
acc )
in
let target_path =
if Filename.is_absolute target_path then target_path else Config.project_root ^/ target_path
in
match Sys.is_directory target_path with
| `Yes ->
(* output path is directory, so should contain either a capture DB or an [infer-deps.txt] file *)
expand_dir acc (target, target_path)
| `No | `Unknown -> (
(* output path is not a directory, so assume it's an intermediate genrule output containing the
output path of the underlying capture target *)
match Utils.read_file target_path with
| Ok [new_target_path] ->
expand_dir acc (target, new_target_path)
| Ok _ ->
L.internal_error "Couldn't parse intermediate deps file %s@." target_path ;
acc
| Error error ->
L.internal_error "Error %s@\nCouldn't read intermediate deps file %s@." error target_path ;
acc )
let infer_deps_of_build_report build_report =
match read_and_parse_report build_report with
| None ->
L.die InternalError "Couldn't parse buck build report: %s@." build_report
| Some target_path_list ->
let infer_deps_lines =
List.fold target_path_list ~init:[] ~f:expand_target
|> List.dedup_and_sort ~compare:String.compare
in
let infer_deps = ResultsDir.get_path CaptureDependencies in
Utils.with_file_out infer_deps ~f:(fun out_channel ->
Out_channel.output_lines out_channel infer_deps_lines )
let capture build_cmd =
let prog, buck_cmd = (List.hd_exn build_cmd, List.tl_exn build_cmd) in
L.progress "Querying buck for java flavor capture targets...@." ;
@ -34,7 +171,7 @@ let capture build_cmd =
else
let time0 = Mtime_clock.counter () in
Buck.wrap_buck_call ~label:"build" updated_buck_cmd |> ignore ;
BuckGenrule.infer_deps_of_build_report build_report_file ;
infer_deps_of_build_report build_report_file ;
L.progress "Java flavor capture took %a.@." Mtime.Span.pp (Mtime_clock.count time0) ;
ResultsDir.RunState.set_merge_capture true ;
()

@ -18,10 +18,8 @@ type mode =
| Analyze
| Ant of {prog: string; args: string list}
| BuckClangFlavor of {build_cmd: string list}
| BuckCombinedGenrule of {build_cmd: string list}
| BuckCompilationDB of {deps: BuckMode.clang_compilation_db_deps; prog: string; args: string list}
| BuckGenrule of {prog: string}
| BuckGenruleMaster of {build_cmd: string list}
| BuckJavaFlavor of {build_cmd: string list}
| Clang of {compiler: Clang.compiler; prog: string; args: string list}
| ClangCompilationDB of {db_files: [`Escaped of string | `Raw of string] list}
@ -41,15 +39,11 @@ let pp_mode fmt = function
F.fprintf fmt "Ant driver mode:@\nprog = '%s'@\nargs = %a" prog Pp.cli_args args
| BuckClangFlavor {build_cmd} ->
F.fprintf fmt "BuckClangFlavor driver mode: build_cmd = %a" Pp.cli_args build_cmd
| BuckCombinedGenrule {build_cmd} ->
F.fprintf fmt "BuckCombinedGenrule driver mode: build_cmd = %a" Pp.cli_args build_cmd
| BuckCompilationDB {deps; prog; args} ->
F.fprintf fmt "BuckCompilationDB driver mode:@\nprog = '%s'@\nargs = %a@\ndeps = %a" prog
Pp.cli_args args BuckMode.pp_clang_compilation_db_deps deps
| BuckGenrule {prog} ->
F.fprintf fmt "BuckGenRule driver mode:@\nprog = '%s'" prog
| BuckGenruleMaster {build_cmd} ->
F.fprintf fmt "BuckGenrule driver mode:@\nbuild command = %a" Pp.cli_args build_cmd
| BuckJavaFlavor {build_cmd} ->
F.fprintf fmt "BuckJavaFlavor driver mode:@\nbuild command = %a" Pp.cli_args build_cmd
| Clang {prog; args} ->
@ -113,9 +107,6 @@ let capture ~changed_files = function
| BuckClangFlavor {build_cmd} ->
L.progress "Capturing in buck mode...@." ;
BuckFlavors.capture build_cmd
| BuckCombinedGenrule {build_cmd} ->
L.progress "Capturing in buck combined genrule mode...@." ;
BuckGenrule.capture CombinedGenrule build_cmd
| BuckCompilationDB {deps; prog; args} ->
L.progress "Capturing using Buck's compilation database...@." ;
let db_files =
@ -125,9 +116,6 @@ let capture ~changed_files = function
| BuckGenrule {prog} ->
L.progress "Capturing for Buck genrule compatibility...@." ;
JMain.from_arguments prog
| BuckGenruleMaster {build_cmd} ->
L.progress "Capturing for BuckGenruleMaster integration...@." ;
BuckGenrule.capture JavaGenruleMaster build_cmd
| BuckJavaFlavor {build_cmd} ->
L.progress "Capturing for BuckJavaFlavor integration...@." ;
BuckJavaFlavor.capture build_cmd
@ -252,7 +240,7 @@ let analyze_and_report ?suppress_console_report ~changed_files mode =
&& InferCommand.equal Run Config.command ->
(* if doing capture + analysis of buck with flavors, we always need to merge targets before the analysis phase *)
true
| Analyze | BuckGenruleMaster _ | BuckCombinedGenrule _ | BuckJavaFlavor _ | Gradle _ ->
| Analyze | BuckJavaFlavor _ | Gradle _ ->
ResultsDir.RunState.get_merge_capture ()
| _ ->
false
@ -336,13 +324,11 @@ let assert_supported_build_system build_system =
match Config.buck_mode with
| None ->
error_no_buck_mode_specified ()
| Some CombinedGenrule ->
(`ClangJava, "buck combined genrule")
| Some ClangFlavors ->
(`Clang, "buck with flavors")
| Some (ClangCompilationDB _) ->
(`Clang, "buck compilation database")
| Some (JavaGenruleMaster | JavaFlavor) ->
| Some JavaFlavor ->
(`Java, Config.string_of_build_system build_system)
in
assert_supported_mode analyzer build_string
@ -369,8 +355,6 @@ let mode_of_build_command build_cmd (buck_mode : BuckMode.t option) =
Ant {prog; args}
| BBuck, None ->
error_no_buck_mode_specified ()
| BBuck, Some CombinedGenrule ->
BuckCombinedGenrule {build_cmd}
| BBuck, Some (ClangCompilationDB deps) ->
BuckCompilationDB {deps; prog; args= List.append args Config.buck_build_args}
| BBuck, Some ClangFlavors when Config.is_checker_enabled Linters ->
@ -378,8 +362,6 @@ let mode_of_build_command build_cmd (buck_mode : BuckMode.t option) =
"WARNING: the linters require --buck-compilation-database to be set.@ Alternatively, \
set --no-linters to disable them and this warning.@." ;
BuckClangFlavor {build_cmd}
| BBuck, Some JavaGenruleMaster ->
BuckGenruleMaster {build_cmd}
| BBuck, Some JavaFlavor ->
BuckJavaFlavor {build_cmd}
| BBuck, Some ClangFlavors ->

@ -15,10 +15,8 @@ type mode =
| Analyze
| Ant of {prog: string; args: string list}
| BuckClangFlavor of {build_cmd: string list}
| BuckCombinedGenrule of {build_cmd: string list}
| BuckCompilationDB of {deps: BuckMode.clang_compilation_db_deps; prog: string; args: string list}
| BuckGenrule of {prog: string}
| BuckGenruleMaster of {build_cmd: string list}
| BuckJavaFlavor of {build_cmd: string list}
| Clang of {compiler: Clang.compiler; prog: string; args: string list}
| ClangCompilationDB of {db_files: [`Escaped of string | `Raw of string] list}

@ -1,2 +0,0 @@
[buildfile]
includes = //DEFS

@ -1,91 +0,0 @@
import os
original_cxx_library = cxx_library
original_java_library = java_library
infer_clang_flavor = "infer-capture-all"
def _cxx_infer_capture_genrule(name):
cmd = "echo $(location :{}#{}) > $OUT".format(name, infer_clang_flavor)
genrule(
name = name + "_infer",
out = "dummy_out",
cmd = cmd,
)
def cxx_library(name, **kwargs):
_cxx_infer_capture_genrule(name)
new_kwargs = dict(kwargs, labels=kwargs.get("labels", []) + ["infer_enabled"])
original_cxx_library(
name=name,
**new_kwargs
)
def _get_project_root():
return "\$(git rev-parse --show-toplevel)/infer/tests/build_systems/buck_combined"
def _infer_capture_genrule(
name,
srcs
):
args = [
"--jobs",
"1",
"--genrule-mode",
"--quiet",
"--no-progress-bar",
"--results-dir",
"$OUT",
"--sourcepath",
"$SRCDIR",
"--project-root",
_get_project_root(),
"--classpath",
"$(classpath :{})".format(name),
"--generated-classes",
"$(location :{})".format(name),
"capture",
]
args_file = os.path.join("$TMP", "args.txt")
subcommands = [
"echo {} >> {}".format(arg, args_file)
for arg in args
] + [
"infer @" + args_file
]
genrule(
name = name + "_infer",
srcs = srcs,
cmd = " && ".join(subcommands),
out = "infer_out",
labels = ["infer_genrule"],
)
def _make_infer_capture_genrule(name, kwargs):
java_sources = [
f
for f in kwargs.get("srcs", [])
if f.endswith(".java")
]
if java_sources != []:
_infer_capture_genrule(name, java_sources)
kwargs["labels"] = kwargs.get("labels", []) + ["infer_enabled"]
return kwargs
def java_library(name, **kwargs):
new_kwargs = _make_infer_capture_genrule(name, kwargs)
original_java_library(
name=name,
**new_kwargs
)

@ -1,26 +0,0 @@
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
TESTS_DIR = ../..
ROOT_DIR = $(TESTS_DIR)/../..
BUCK_TARGET = //clang:hello //java:hello
SOURCES = clang/hello.c clang/hello2.c
OBJECTS = buck-out/gen/clang/hello\#compile-hello.c.o1f717d69,default/hello.c.o
INFER_OPTIONS = --report-custom-error --developer-mode --no-linters --buck-combined
INFERPRINT_OPTIONS = --issues-tests
CLEAN_EXTRA = buck-out
include $(TESTS_DIR)/infer.make
$(OBJECTS): $(SOURCES)
$(QUIET)$(call silent_on_success,Compiling Buck flavors tests,\
$(BUCK) build --no-cache $(BUCK_TARGET))
infer-out/report.json: $(CLANG_DEPS) $(SOURCES) $(MAKEFILE_LIST)
$(QUIET)$(BUCK) clean
$(call silent_on_success,Testing infer-run Buck combined genrule integration,\
$(INFER_BIN) $(INFER_OPTIONS) run --results-dir $(CURDIR)/infer-out -- \
$(BUCK) build --no-cache $(BUCK_TARGET))

@ -1,6 +0,0 @@
cxx_library(
name = 'hello',
srcs = [
'hello.c', 'hello2.c',
],
)

@ -1,13 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <stdlib.h>
void test() {
int* s = NULL;
*s = 42;
}

@ -1,13 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <stdlib.h>
void test2() {
int* s = NULL;
*s = 42;
}

@ -1,3 +0,0 @@
clang/hello.c, test, 2, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure test()]
clang/hello2.c, test2, 2, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure test2()]
java/NullDeref.java, NullDeref.callToStringWithNullBad():java.lang.String, 1, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure callToStringWithNullBad(),start of procedure myToString(...),Skipping toString(): unknown method]

@ -1,6 +0,0 @@
java_library(
name='hello',
srcs=glob(["*.java"]),
deps=[],
visibility=['PUBLIC'],
)

@ -1,16 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
public class NullDeref {
private static String myToString(Object foo) {
return foo.toString();
}
public String callToStringWithNullBad() {
return myToString(null);
}
}

@ -4,6 +4,6 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package genrulecapture.annotations;
package buck_java_flavor.annotations;
public @interface ThreadSafe {}

@ -1,2 +1,2 @@
module2/Class2.java, genrulecapture.module2.Class2.get():int, 22, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to int Class1.get(),access to `this.c.x`,<Write trace>,call to void Class1.set(int),access to `this.c.x`]
module2/Class2.java, genrulecapture.module2.Class2.set(int):void, 18, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [call to void Class1.set(int),access to `this.c.x`]
module2/Class2.java, buck_java_flavor.module2.Class2.get():int, 22, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to int Class1.get(),access to `this.c.x`,<Write trace>,call to void Class1.set(int),access to `this.c.x`]
module2/Class2.java, buck_java_flavor.module2.Class2.set(int):void, 18, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [call to void Class1.set(int),access to `this.c.x`]

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
package genrulecapture.module1;
package buck_java_flavor.module1;
public class Class1 {
int x;

@ -5,10 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/
package genrulecapture.module2;
package buck_java_flavor.module2;
import genrulecapture.annotations.ThreadSafe;
import genrulecapture.module1.Class1;
import buck_java_flavor.annotations.ThreadSafe;
import buck_java_flavor.module1.Class1;
@ThreadSafe
public class Class2 {

@ -1,9 +0,0 @@
[buildfile]
includes = //DEFS
[project]
ignore = .git, .ml, .mli
[java]
source_level = 8
target_level = 8

@ -1,78 +0,0 @@
import os
original_java_library = java_library
original_android_library = android_library
def _get_project_root():
return "\$(git rev-parse --show-toplevel)/infer/tests/build_systems/genrulecapture"
def _infer_capture_genrule(
name,
srcs
):
args = [
"--jobs",
"1",
"--genrule-mode",
"--quiet",
"--no-progress-bar",
"--results-dir",
"$OUT",
"--sourcepath",
"$SRCDIR",
"--project-root",
_get_project_root(),
"--classpath",
"$(classpath :{})".format(name),
"--generated-classes",
"$(location :{})".format(name),
"capture",
]
args_file = os.path.join("$TMP", "args.txt")
subcommands = [
"echo {} >> {}".format(arg, args_file)
for arg in args
] + [
"infer @" + args_file
]
genrule(
name = name + "_infer",
srcs = srcs,
cmd = " && ".join(subcommands),
out = "infer_out",
labels = ["infer_genrule"],
)
def _make_infer_capture_genrule(name, kwargs):
java_sources = [
f
for f in kwargs.get("srcs", [])
if f.endswith(".java")
]
if java_sources != []:
_infer_capture_genrule(name, java_sources)
kwargs["labels"] = kwargs.get("labels", []) + ["infer_enabled"]
return kwargs
def java_library(name, **kwargs):
new_kwargs = _make_infer_capture_genrule(name, kwargs)
original_java_library(
name=name,
**new_kwargs
)
def android_library(name, **kwargs):
new_kwargs = _make_infer_capture_genrule(name, kwargs)
original_android_library(
name=name,
**new_kwargs
)

@ -1,21 +0,0 @@
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
TESTS_DIR = ../..
BUCK_TARGET = //module2:module2
CLEAN_EXTRA = buck-out
SOURCES = $(shell find . -name '*.java')
INFERPRINT_OPTIONS = --issues-tests
INFER_OPTIONS = --buck-java --debug-exceptions
include $(TESTS_DIR)/infer.make
$(INFER_OUT)/report.json: $(MAKEFILE_LIST) $(SOURCES)
$(QUIET)$(BUCK) clean
$(call silent_on_success,Testing genrule capture integration in $(TEST_REL_DIR),\
$(INFER_BIN) --results-dir $(@D) $(INFER_OPTIONS) -- \
$(BUCK) build --no-cache $(BUCK_TARGET))

@ -1,7 +0,0 @@
java_library(
name='annotations',
srcs=['ThreadSafe.java'],
visibility=[
'PUBLIC'
],
)

@ -1,9 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package genrulecapture.annotations;
public @interface ThreadSafe {}

@ -1,2 +0,0 @@
module2/Class2.java, genrulecapture.module2.Class2.get():int, 22, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to int Class1.get(),access to `this.c.x`,<Write trace>,call to void Class1.set(int),access to `this.c.x`]
module2/Class2.java, genrulecapture.module2.Class2.set(int):void, 18, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [call to void Class1.set(int),access to `this.c.x`]

@ -1,10 +0,0 @@
java_library(
name='module1',
srcs=glob(["*.java"]),
deps=[
'//annotations:annotations',
],
visibility=[
'PUBLIC'
],
)

@ -1,20 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package genrulecapture.module1;
public class Class1 {
int x;
public void set(int d) {
x = d;
}
public int get() {
return x;
}
}

@ -1,9 +0,0 @@
java_library(
name='module2',
srcs=glob(["*.java"]),
deps=[
'//module1:module1',
'//annotations:annotations',
'//module3:module3',
]
)

@ -1,24 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package genrulecapture.module2;
import genrulecapture.annotations.ThreadSafe;
import genrulecapture.module1.Class1;
@ThreadSafe
public class Class2 {
Class1 c;
void set(int x) {
c.set(x);
}
int get() {
return c.get();
}
}

@ -1,9 +0,0 @@
cxx_library(
name = 'module3',
visibility = [
'PUBLIC',
],
srcs = [
'some_c_code.c',
],
)

@ -1,13 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <stdlib.h>
void some_c_func() {
int* s = NULL;
*s = 42;
}
Loading…
Cancel
Save