[rundiff] thread the changed files list through the code instead of using the Config-time value

Summary: Needed in a later diff to be able to compute the set of changed files *during* an infer execution.

Reviewed By: jberdine

Differential Revision: D5319667

fbshipit-source-id: 226ec91
master
Jules Villard 8 years ago committed by Facebook Github Bot
parent 6388910b96
commit 83148a71aa

@ -108,10 +108,25 @@ let print_legend () => {
L.progress "@\n@?" L.progress "@\n@?"
}; };
let cluster_should_be_analyzed cluster => { let cluster_should_be_analyzed ::changed_files cluster => {
let fname = DB.source_dir_to_string cluster; let fname = DB.source_dir_to_string cluster;
let in_ondemand_config = /* whether [fname] is one of the [changed_files] */
Option.map f::(fun dirs => String.Set.mem dirs fname) Ondemand.dirs_to_analyze; let is_changed_file = {
/* set of source dirs to analyze inside infer-out/captured/ */
let source_dirs_to_analyze changed_files =>
SourceFile.Set.fold
(
fun source_file source_dir_set => {
let source_dir = DB.source_dir_from_source_file source_file;
String.Set.add source_dir_set (DB.source_dir_to_string source_dir)
}
)
changed_files
String.Set.empty;
Option.map f::source_dirs_to_analyze changed_files |> (
fun dirs_opt => Option.map dirs_opt f::(fun dirs => String.Set.mem dirs fname)
)
};
let check_modified () => { let check_modified () => {
let modified = DB.file_was_updated_after_start (DB.filename_from_string fname); let modified = DB.file_was_updated_after_start (DB.filename_from_string fname);
if (modified && Config.developer_mode) { if (modified && Config.developer_mode) {
@ -119,16 +134,14 @@ let cluster_should_be_analyzed cluster => {
}; };
modified modified
}; };
switch in_ondemand_config { switch is_changed_file {
| Some b => | Some b => b
/* ondemand config file is specified */
b
| None when Config.reactive_mode => check_modified () | None when Config.reactive_mode => check_modified ()
| None => true | None => true
} }
}; };
let main makefile => { let main ::changed_files ::makefile => {
BuiltinDefn.init (); BuiltinDefn.init ();
RegisterCheckers.register (); RegisterCheckers.register ();
switch Config.modified_targets { switch Config.modified_targets {
@ -145,13 +158,14 @@ let main makefile => {
MergeCapture.merge_captured_targets () MergeCapture.merge_captured_targets ()
}; };
let all_clusters = DB.find_source_dirs (); let all_clusters = DB.find_source_dirs ();
let clusters_to_analyze = List.filter f::cluster_should_be_analyzed all_clusters; let clusters_to_analyze =
List.filter f::(cluster_should_be_analyzed ::changed_files) all_clusters;
let n_clusters_to_analyze = List.length clusters_to_analyze; let n_clusters_to_analyze = List.length clusters_to_analyze;
L.progress L.progress
"Found %d%s source file%s to analyze in %s@." "Found %d%s source file%s to analyze in %s@."
n_clusters_to_analyze n_clusters_to_analyze
( (
if (Config.reactive_mode || Option.is_some Ondemand.dirs_to_analyze) { if (Config.reactive_mode || Option.is_some changed_files) {
" (out of " ^ string_of_int (List.length all_clusters) ^ ")" " (out of " ^ string_of_int (List.length all_clusters) ^ ")"
} else { } else {
"" ""

@ -13,6 +13,6 @@ open! IStd;
/** Main module for the analysis after the capture phase */ /** Main module for the analysis after the capture phase */
/** Given a name of the Makefile to use for multicore analysis, analyze the captured code */ /** Given a name of the Makefile to use for multicore analysis, analyze the captured code */
let main: string => unit; let main: changed_files::option SourceFile.Set.t => makefile::string => unit;
let register_perf_stats_report: unit => unit; let register_perf_stats_report: unit => unit;

@ -243,13 +243,13 @@ let capture_with_compilation_database db_files =
let compilation_database = CompilationDatabase.from_json_files db_files in let compilation_database = CompilationDatabase.from_json_files db_files in
CaptureCompilationDatabase.capture_files_in_database compilation_database CaptureCompilationDatabase.capture_files_in_database compilation_database
let capture = function let capture ~changed_files = function
| Analyze -> | Analyze ->
() ()
| BuckCompilationDB (prog, args) -> | BuckCompilationDB (prog, args) ->
L.progress "Capturing using Buck's compilation database...@."; L.progress "Capturing using Buck's compilation database...@.";
let json_cdb = CaptureCompilationDatabase.get_compilation_database_files_buck ~prog ~args in let json_cdb = CaptureCompilationDatabase.get_compilation_database_files_buck ~prog ~args in
capture_with_compilation_database json_cdb capture_with_compilation_database ~changed_files json_cdb
| BuckGenrule path -> | BuckGenrule path ->
L.progress "Capturing for Buck genrule compatibility...@."; L.progress "Capturing for Buck genrule compatibility...@.";
JMain.from_arguments path JMain.from_arguments path
@ -258,7 +258,7 @@ let capture = function
Clang.capture compiler ~prog ~args Clang.capture compiler ~prog ~args
| ClangCompilationDB db_files -> | ClangCompilationDB db_files ->
L.progress "Capturing using compilation database...@."; L.progress "Capturing using compilation database...@.";
capture_with_compilation_database db_files capture_with_compilation_database ~changed_files db_files
| Javac (compiler, prog, args) -> | Javac (compiler, prog, args) ->
L.progress "Capturing in javac mode...@."; L.progress "Capturing in javac mode...@.";
Javac.capture compiler ~prog ~args Javac.capture compiler ~prog ~args
@ -327,13 +327,13 @@ let capture = function
check_xcpretty (); check_xcpretty ();
let json_cdb = let json_cdb =
CaptureCompilationDatabase.get_compilation_database_files_xcodebuild ~prog ~args in CaptureCompilationDatabase.get_compilation_database_files_xcodebuild ~prog ~args in
capture_with_compilation_database json_cdb capture_with_compilation_database ~changed_files json_cdb
let run_parallel_analysis () = let run_parallel_analysis ~changed_files =
let multicore_dir = Config.results_dir ^/ Config.multicore_dir_name in let multicore_dir = Config.results_dir ^/ Config.multicore_dir_name in
rmtree multicore_dir ; rmtree multicore_dir ;
Unix.mkdir_p multicore_dir ; Unix.mkdir_p multicore_dir ;
InferAnalyze.main (multicore_dir ^/ "Makefile") ; InferAnalyze.main ~changed_files ~makefile:(multicore_dir ^/ "Makefile") ;
run_command run_command
~prog:"make" ~args:( ~prog:"make" ~args:(
"-C" :: multicore_dir :: "-C" :: multicore_dir ::
@ -343,11 +343,11 @@ let run_parallel_analysis () =
(if Config.debug_mode then [] else ["-s"]) (if Config.debug_mode then [] else ["-s"])
) (fun _ -> ()) ) (fun _ -> ())
let execute_analyze () = let execute_analyze ~changed_files =
if Int.equal Config.jobs 1 || Config.cluster_cmdline <> None then if Int.equal Config.jobs 1 || Config.cluster_cmdline <> None then
InferAnalyze.main "" InferAnalyze.main ~changed_files ~makefile:""
else else
run_parallel_analysis () run_parallel_analysis ~changed_files
let report () = let report () =
let report_csv = let report_csv =
@ -378,7 +378,7 @@ let report () =
"** Error running the reporting script:@\n** %s %s@\n** See error above@." "** Error running the reporting script:@\n** %s %s@\n** See error above@."
prog (String.concat ~sep:" " args) prog (String.concat ~sep:" " args)
let analyze driver_mode = let analyze driver_mode ~changed_files =
let should_analyze, should_report = match driver_mode, Config.analyzer with let should_analyze, should_report = match driver_mode, Config.analyzer with
| PythonCapture (BBuck, _), _ -> | PythonCapture (BBuck, _), _ ->
(* In Buck mode when compilation db is not used, analysis is invoked either from capture or (* In Buck mode when compilation db is not used, analysis is invoked either from capture or
@ -398,7 +398,7 @@ let analyze driver_mode =
check_captured_empty driver_mode) then ( check_captured_empty driver_mode) then (
L.user_error "There was nothing to analyze.@\n@." ; L.user_error "There was nothing to analyze.@\n@." ;
) else if should_analyze then ) else if should_analyze then
execute_analyze (); execute_analyze ~changed_files;
if should_report && Config.report then report () if should_report && Config.report then report ()
(** as the Config.fail_on_bug flag mandates, exit with error when an issue is reported *) (** as the Config.fail_on_bug flag mandates, exit with error when an issue is reported *)
@ -512,6 +512,17 @@ let get_driver_mode () =
| None -> | None ->
driver_mode_of_build_cmd (List.rev Config.rest) driver_mode_of_build_cmd (List.rev Config.rest)
let read_config_changed_files () =
match Config.changed_files_index with
| None ->
None
| Some index -> match Utils.read_file index with
| Ok lines ->
Some (SourceFile.changed_sources_from_changed_files lines)
| Error error ->
L.external_error "Error reading the changed files index '%s': %s@." index error ;
None
let infer_mode () = let infer_mode () =
let driver_mode = get_driver_mode () in let driver_mode = get_driver_mode () in
if not (equal_driver_mode driver_mode Analyze || if not (equal_driver_mode driver_mode Analyze ||
@ -528,8 +539,9 @@ let infer_mode () =
Unix.unsetenv "MAKEFLAGS"; Unix.unsetenv "MAKEFLAGS";
register_perf_stats_report () ; register_perf_stats_report () ;
if not Config.buck_cache_mode then touch_start_file_unless_continue () ; if not Config.buck_cache_mode then touch_start_file_unless_continue () ;
capture driver_mode ; let changed_files = read_config_changed_files () in
analyze driver_mode ; capture driver_mode ~changed_files ;
analyze driver_mode ~changed_files ;
if CLOpt.is_originator then ( if CLOpt.is_originator then (
let in_buck_mode = match driver_mode with | PythonCapture (BBuck, _) -> true | _ -> false in let in_buck_mode = match driver_mode with | PythonCapture (BBuck, _) -> true | _ -> false in
StatsAggregator.generate_files () ; StatsAggregator.generate_files () ;
@ -602,7 +614,7 @@ let () =
| Some cluster -> F.fprintf fmt "of cluster %s" (Filename.basename cluster) in | Some cluster -> F.fprintf fmt "of cluster %s" (Filename.basename cluster) in
L.environment_info "Starting analysis %a" pp_cluster_opt Config.cluster_cmdline; L.environment_info "Starting analysis %a" pp_cluster_opt Config.cluster_cmdline;
InferAnalyze.register_perf_stats_report (); InferAnalyze.register_perf_stats_report ();
analyze Analyze analyze Analyze ~changed_files:(read_config_changed_files ())
| Clang -> | Clang ->
let prog, args = match Array.to_list Sys.argv with let prog, args = match Array.to_list Sys.argv with
| prog::args -> prog, args | prog::args -> prog, args

@ -15,18 +15,6 @@ open! PVariant
module L = Logging module L = Logging
module F = Format module F = Format
(** Optional set of source dirs to analyze in on-demand mode. If None then all source dirs
will be analyzed *)
let dirs_to_analyze =
let process_changed_files changed_files =
SourceFile.Set.fold
(fun source_file source_dir_set ->
let source_dir = DB.source_dir_from_source_file source_file in
String.Set.add source_dir_set (DB.source_dir_to_string source_dir)
)
changed_files String.Set.empty in
Option.map ~f:process_changed_files SourceFile.changed_files_set
type analyze_ondemand = Specs.summary -> Procdesc.t -> Specs.summary type analyze_ondemand = Specs.summary -> Procdesc.t -> Specs.summary
type get_proc_desc = Typ.Procname.t -> Procdesc.t option type get_proc_desc = Typ.Procname.t -> Procdesc.t option

@ -11,10 +11,6 @@ open! IStd
(** Module for on-demand analysis. *) (** Module for on-demand analysis. *)
(** Optional set of source dirs to analyze in on-demand mode. If None then all source dirs
will be analyzed *)
val dirs_to_analyze : String.Set.t option
type analyze_ondemand = Specs.summary -> Procdesc.t -> Specs.summary type analyze_ondemand = Specs.summary -> Procdesc.t -> Specs.summary
type get_proc_desc = Typ.Procname.t -> Procdesc.t option type get_proc_desc = Typ.Procname.t -> Procdesc.t option

@ -135,23 +135,15 @@ let create ?(warn_on_error=true) path =
else else
from_abs_path ~warn_on_error path from_abs_path ~warn_on_error path
let changed_files_set = let changed_sources_from_changed_files changed_files =
match Config.changed_files_index with List.fold changed_files ~init:Set.empty ~f:(fun changed_files_set line ->
| None -> let source_file = create line in
None let changed_files' = Set.add source_file changed_files_set in
| Some index -> match Utils.read_file index with (* Add source corresponding to changed header if it exists *)
| Ok lines -> match of_header source_file with
Some (List.fold lines ~init:Set.empty ~f:(fun changed_files line -> | Some src -> Set.add src changed_files'
let source_file = create line in | None -> changed_files'
let changed_files' = Set.add source_file changed_files in )
(* Add source corresponding to changed header if it exists *)
match of_header source_file with
| Some src -> Set.add src changed_files'
| None -> changed_files'
))
| Error error ->
L.user_error "Error reading the changed files index '%s': %s@." index error ;
None
module UNSAFE = struct module UNSAFE = struct
let from_string str = let from_string str =

@ -30,7 +30,7 @@ val is_invalid : t -> bool
(** Set of files read from --changed-files-index file, None if option not specified (** Set of files read from --changed-files-index file, None if option not specified
NOTE: it may include extra source_files if --changed-files-index contains paths to NOTE: it may include extra source_files if --changed-files-index contains paths to
header files *) header files *)
val changed_files_set : Set.t option val changed_sources_from_changed_files : string list -> Set.t
(** Invalid source file *) (** Invalid source file *)
val invalid : string -> t val invalid : string -> t

@ -18,17 +18,6 @@ let capture_text =
if Config.equal_analyzer Config.analyzer Config.Linters then "linting" if Config.equal_analyzer Config.analyzer Config.Linters then "linting"
else "translating" else "translating"
(** Read the files to compile from the changed files index. *)
let should_capture_file_from_index () =
match SourceFile.changed_files_set with
| None ->
(match Config.changed_files_index with
| Some index ->
Process.print_error_and_exit "Error reading the changed files index %s.@\n%!" index
| None -> function _ -> true)
| Some files_set ->
function source_file -> SourceFile.Set.mem source_file files_set
let create_files_stack compilation_database should_capture_file = let create_files_stack compilation_database should_capture_file =
let stack = Stack.create () in let stack = Stack.create () in
let add_to_stack file _ = if should_capture_file file then let add_to_stack file _ = if should_capture_file file then
@ -140,8 +129,14 @@ let get_compilation_database_files_xcodebuild ~prog ~args =
L.external_error "There was an error executing the build command"; L.external_error "There was an error executing the build command";
exit 1 exit 1
let capture_files_in_database compilation_database = let capture_files_in_database ~changed_files compilation_database =
run_compilation_database compilation_database (should_capture_file_from_index ()) let filter_changed = match changed_files with
| None ->
fun _ -> true
| Some changed_files_set ->
fun source_file -> SourceFile.Set.mem source_file changed_files_set
in
run_compilation_database compilation_database filter_changed
let capture_file_in_database compilation_database source_file = let capture_file_in_database compilation_database source_file =
run_compilation_database compilation_database (SourceFile.equal source_file) run_compilation_database compilation_database (SourceFile.equal source_file)

@ -9,10 +9,10 @@
open! IStd open! IStd
(** capture_files_in_database file runs the capture of the files for which (** Run the capture of the files for which we have compilation commands in the database and in
we have compilation commands in the database. If the option changed-files-index [changed_files], if specified. *)
is passed, we only capture the files there *) val capture_files_in_database : changed_files:SourceFile.Set.t option ->
val capture_files_in_database : CompilationDatabase.t -> unit CompilationDatabase.t -> unit
val capture_file_in_database : CompilationDatabase.t -> SourceFile.t -> unit val capture_file_in_database : CompilationDatabase.t -> SourceFile.t -> unit

Loading…
Cancel
Save