[buck/java2] rely on (and modify) PATH to find infer binary to improve caching

Summary:
The genrule-capture integration with Java relies on a buck config flag `infer.infer_bin=<path to infer>` (see test changes in `DEFS` below).
In a CI environment where the infer binary is checked out under a random directory, this means that the buck genrule is keyed by a random string (the path to infer), and this defeats caching.

Switch to the following contract: the genrule target does not expect a config flag at all.  Instead it runs whichever `infer` binary is in the path.  To make sure the binary is the same one with the originator, the capture integration runs buck under a modified `PATH` where the originator `infer` is sure to be the first matching entry.

NB cache invalidation is still OK because we rely on `infer.version` buck config flag, which will be hashed into the rulekey.

Reviewed By: jvillard

Differential Revision: D16332696

fbshipit-source-id: 2975d5c26
master
Nikos Gorogiannis 6 years ago committed by Facebook Github Bot
parent 998e7c8fe3
commit af12e55344

@ -89,8 +89,6 @@ val etc_dir : string
val events_dir_name : string
val exe_basename : string
val fail_on_issue_exit_code : int
val frontend_stats_dir_name : string

@ -67,6 +67,8 @@ val consume_in : In_channel.t -> unit
val echo_in : In_channel.t -> unit
(** echo the lines we get to stdout until End_of_file is reached *)
val with_channel_in : f:(string -> unit) -> In_channel.t -> unit
val with_process_in : string -> (In_channel.t -> 'a) -> 'a * Unix.Exit_or_signal.t
val with_process_lines :

@ -160,9 +160,7 @@ let die_if_empty f = function [] -> f L.(die UserError) | l -> l
let buck_config =
lazy
( if Config.genrule_master_mode then
[ "infer.version=" ^ Version.versionString
; "infer.infer_bin=" ^ Config.bin_dir ^/ Config.exe_basename
; "infer.mode=capture" ]
["infer.version=" ^ Version.versionString; "infer.mode=capture"]
|> List.fold ~init:[] ~f:(fun acc f -> "--config" :: f :: acc)
else [] )

@ -24,9 +24,26 @@ let write_infer_deps infile =
let run_buck_capture cmd =
let buck_output_file = Filename.temp_file "buck_output" ".log" in
let shell_cmd = List.map ~f:Escape.escape_shell cmd |> String.concat ~sep:" " in
let shell_cmd_redirected = Printf.sprintf "%s >'%s'" shell_cmd buck_output_file in
match Utils.with_process_in shell_cmd_redirected Utils.consume_in |> snd with
let shell_cmd =
List.map ~f:Escape.escape_shell cmd
|> String.concat ~sep:" "
|> fun cmd -> Printf.sprintf "%s >'%s'" cmd buck_output_file
in
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 env = `Extend [(path_var, new_path)] in
let ({stdin; stdout; stderr; pid} : Unix.Process_info.t) =
Unix.create_process_env ~prog:"sh" ~args:["-c"; shell_cmd] ~env ()
in
let buck_stderr = Unix.in_channel_of_descr stderr in
Utils.with_channel_in buck_stderr ~f:(L.progress "BUCK: %s@.") ;
Unix.close stdin ;
Unix.close stdout ;
In_channel.close buck_stderr ;
match Unix.waitpid pid with
| Ok () ->
write_infer_deps buck_output_file ; Unix.unlink buck_output_file
| Error _ as err ->

@ -3,9 +3,6 @@ import os
original_java_library = java_library
original_android_library = android_library
def _get_infer_bin():
return read_config("infer", "infer_bin")
def _get_project_root():
return "\$(git rev-parse --show-toplevel)/infer/tests/build_systems/genrulecapture"
@ -38,7 +35,7 @@ def _infer_capture_genrule(
"echo {} >> {}".format(arg, args_file)
for arg in args
] + [
" ".join([_get_infer_bin(), "@" + args_file])
"infer @" + args_file
]
genrule(

Loading…
Cancel
Save