Summary: Record the db schema, infer version, and run dates into infer-out/.infer_runstate.json. This allows us to check on startup whether the results directory was generated using a compatible version of infer or not, and give a better error message in the latter case than some SQLite error about mismatching tables. This will be used in a follow-up diff to record capture phases too, and avoid relying on filesystem timestamps of the infer-out/capture/foo/ directories for reactive analysis. Had to change some tests Makefiles to make sure they do not attempt to re-use stale infer-out directories, which would now fail the run. The stale infer-out directory gets deleted if `--force-delete-results-dir` is passed (but a warning still gets printed). Reviewed By: mbouaziz Differential Revision: D6760787 fbshipit-source-id: f36f7dfmaster
parent
0c9b025857
commit
66ad5c3018
@ -0,0 +1,23 @@
|
||||
type infer_version = {
|
||||
major: int;
|
||||
minor: int;
|
||||
patch: int;
|
||||
commit: string;
|
||||
}
|
||||
|
||||
type command = string wrap <ocaml
|
||||
t="InferCommand.t"
|
||||
wrap="InferCommand.of_string"
|
||||
unwrap="InferCommand.to_string"
|
||||
>
|
||||
|
||||
type run_info = {
|
||||
date: string;
|
||||
command: command;
|
||||
infer_version: infer_version;
|
||||
}
|
||||
|
||||
type t = {
|
||||
run_sequence: run_info list; (** successive runs that re-used the same results directory *)
|
||||
results_dir_format: string; (** to check if the versions of the results dir are compatible *)
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
(*
|
||||
* Copyright (c) 2018 - present Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*)
|
||||
|
||||
open! IStd
|
||||
|
||||
let run_time_string = Time.now () |> Time.to_string
|
||||
|
||||
let state0 =
|
||||
let open Runstate_t in
|
||||
{ run_sequence= []
|
||||
; results_dir_format=
|
||||
Printf.sprintf "db_filename: %s\ndb_schema: %s" ResultsDatabase.database_filename
|
||||
ResultsDatabase.schema_hum }
|
||||
|
||||
|
||||
let state : Runstate_t.t ref = ref state0
|
||||
|
||||
let add_run_to_sequence () =
|
||||
let run =
|
||||
{ Runstate_t.infer_version= Version.{Runstate_t.major; minor; patch; commit}
|
||||
; date= run_time_string
|
||||
; command= Config.command }
|
||||
in
|
||||
Runstate_t.(state := {(!state) with run_sequence= run :: !state.run_sequence})
|
||||
|
||||
|
||||
let state_filename = ".infer_runstate.json"
|
||||
|
||||
let state_file_path = Config.results_dir ^/ state_filename
|
||||
|
||||
let store () =
|
||||
Utils.with_file_out state_file_path ~f:(fun oc ->
|
||||
Runstate_j.string_of_t !state |> Out_channel.output_string oc )
|
||||
|
||||
|
||||
let load_and_validate () =
|
||||
let error msg =
|
||||
Printf.ksprintf
|
||||
(fun err_msg ->
|
||||
Error
|
||||
(Printf.sprintf
|
||||
"Incompatible results directory '%s':\n%s\nWas '%s' created using an older version of infer?"
|
||||
Config.results_dir err_msg Config.results_dir) )
|
||||
msg
|
||||
in
|
||||
if Sys.file_exists state_file_path <> `Yes then error "save state not found"
|
||||
else
|
||||
try
|
||||
let loaded_state = Ag_util.Json.from_file Runstate_j.read_t state_file_path in
|
||||
if not
|
||||
(String.equal !state.Runstate_t.results_dir_format
|
||||
loaded_state.Runstate_t.results_dir_format)
|
||||
then
|
||||
error "Incompatible formats: found\n %s\n\nbut expected this format:\n %s\n\n"
|
||||
loaded_state.results_dir_format !state.Runstate_t.results_dir_format
|
||||
else (
|
||||
state := loaded_state ;
|
||||
Ok () )
|
||||
with _ -> Error "error reading the save state"
|
||||
|
||||
|
||||
let reset () = state := state0
|
@ -0,0 +1,22 @@
|
||||
(*
|
||||
* Copyright (c) 2018 - present Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*)
|
||||
|
||||
open! IStd
|
||||
|
||||
val add_run_to_sequence : unit -> unit
|
||||
(** add an entry with the current run date *)
|
||||
|
||||
val store : unit -> unit
|
||||
(** save the current state to disk *)
|
||||
|
||||
val load_and_validate : unit -> (unit, string) Result.t
|
||||
(** attempt to load state from disk *)
|
||||
|
||||
val reset : unit -> unit
|
||||
(** reset the in-memory state to what it would be if this were a fresh run of infer *)
|
Loading…
Reference in new issue