[utils] make `read_file` return a `Result.t`

Summary: Small API improvement for better error messages.

Reviewed By: mbouaziz

Differential Revision: D5293334

fbshipit-source-id: ef7f7e2
master
Jules Villard 8 years ago committed by Facebook Github Bot
parent b158f5cd30
commit f38462407e

@ -1026,7 +1026,7 @@ let pp_summary_by_report_kind
let pp_json_report_by_report_kind formats_by_report_kind fname => let pp_json_report_by_report_kind formats_by_report_kind fname =>
switch (Utils.read_file fname) { switch (Utils.read_file fname) {
| Some report_lines => | Ok report_lines =>
let pp_json_issues format_list report => { let pp_json_issues format_list report => {
let pp_json_issue (format_kind, outf: Utils.outfile) => let pp_json_issue (format_kind, outf: Utils.outfile) =>
switch format_kind { switch format_kind {
@ -1048,7 +1048,7 @@ let pp_json_report_by_report_kind formats_by_report_kind fname =>
| _ => () | _ => ()
}; };
List.iter f::pp_report_by_report_kind formats_by_report_kind List.iter f::pp_report_by_report_kind formats_by_report_kind
| None => failwithf "Error reading %s. Does the file exist?" fname | Error error => failwithf "Error reading '%s': %s" fname error
}; };
let pp_lint_issues_by_report_kind formats_by_report_kind error_filter linereader procname error_log => { let pp_lint_issues_by_report_kind formats_by_report_kind error_filter linereader procname error_log => {

@ -71,8 +71,8 @@ let load_data_from_infer_deps file => {
let lines = Utils.read_file file; let lines = Utils.read_file file;
try ( try (
switch lines { switch lines {
| Some l => Ok (List.map f::extract_target_and_path l) | Ok l => Ok (List.map f::extract_target_and_path l)
| None => raise (Failure ("Error reading '" ^ file ^ "'")) | Error error => raise (Failure (Printf.sprintf "Error reading '%s': %s" file error))
} }
) { ) {
| Failure msg => Error msg | Failure msg => Error msg

@ -403,12 +403,15 @@ let analyze driver_mode =
(** 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 *)
let fail_on_issue_epilogue () = let fail_on_issue_epilogue () =
let issues_json = DB.Results_dir.(path_to_filename Abs_root ["report.json"]) in let issues_json = DB.Results_dir.(path_to_filename Abs_root ["report.json"])
match Utils.read_file (DB.filename_to_string issues_json) with |> DB.filename_to_string in
| Some lines -> match Utils.read_file issues_json with
| Ok lines ->
let issues = Jsonbug_j.report_of_string @@ String.concat ~sep:"" lines in let issues = Jsonbug_j.report_of_string @@ String.concat ~sep:"" lines in
if issues <> [] then exit Config.fail_on_issue_exit_code if issues <> [] then exit Config.fail_on_issue_exit_code
| None -> () | Error error ->
L.internal_error "Failed to read report file '%s': %s@." issues_json error ;
()
let log_infer_args driver_mode = let log_infer_args driver_mode =
L.environment_info "INFER_ARGS = %s@\n" L.environment_info "INFER_ARGS = %s@\n"

@ -29,9 +29,10 @@ let modified_targets = ref String.Set.empty
let modified_file file = let modified_file file =
match Utils.read_file file with match Utils.read_file file with
| Some targets -> | Ok targets ->
modified_targets := List.fold ~f:String.Set.add ~init:String.Set.empty targets modified_targets := List.fold ~f:String.Set.add ~init:String.Set.empty targets
| None -> | Error error ->
L.user_error "Failed to read modified targets file '%s': %s@." file error ;
() ()
type stats = type stats =
@ -192,9 +193,11 @@ let process_merge_file deps_file =
then slink ~stats ~skiplevels infer_out_src infer_out_dst then slink ~stats ~skiplevels infer_out_src infer_out_dst
| _ -> | _ ->
() in () in
Option.iter (
~f:(fun lines -> List.iter ~f:process_line lines) match Utils.read_file deps_file with
(Utils.read_file deps_file); | Ok lines -> List.iter ~f:process_line lines
| Error error -> L.internal_error "Couldn't read deps file '%s': %s" deps_file error
);
create_multilinks (); create_multilinks ();
L.progress "Captured results merged.@."; L.progress "Captured results merged.@.";
L.progress "Targets merged: %d@." stats.targets_merged; L.progress "Targets merged: %d@." stats.targets_merged;

@ -1509,10 +1509,11 @@ and specs_library =
if Filename.is_relative path then if Filename.is_relative path then
failwith ("Failing because path " ^ path ^ " is not absolute") in failwith ("Failing because path " ^ path ^ " is not absolute") in
match Utils.read_file (resolve fname) with match Utils.read_file (resolve fname) with
| Some pathlist -> | Ok pathlist ->
List.iter ~f:validate_path pathlist; List.iter ~f:validate_path pathlist;
pathlist pathlist
| None -> failwith ("cannot read file " ^ fname ^ " from cwd " ^ (Sys.getcwd ())) | Error error ->
failwithf "cannot read file '%s' from cwd '%s': %s" fname (Sys.getcwd ()) error
in in
(* Add the newline-separated directories listed in <file> to the list of directories to be (* Add the newline-separated directories listed in <file> to the list of directories to be
searched for .spec files *) searched for .spec files *)

@ -30,8 +30,10 @@ let reset_cache () => String.Table.clear multilink_files_cache;
let read ::dir :option t => { let read ::dir :option t => {
let multilink_fname = Filename.concat dir multilink_file_name; let multilink_fname = Filename.concat dir multilink_file_name;
switch (Utils.read_file multilink_fname) { switch (Utils.read_file multilink_fname) {
| None => None | Error error =>
| Some lines => L.internal_error "Couldn't read multilink file '%s': %s@." multilink_fname error;
None
| Ok lines =>
let links = create (); let links = create ();
List.iter List.iter
f::(fun line => String.Table.set links key::(Filename.basename line) data::line) lines; f::(fun line => String.Table.set links key::(Filename.basename line) data::line) lines;

@ -10,6 +10,8 @@
open! IStd open! IStd
open! PVariant open! PVariant
module L = Logging
let count_newlines (path: string): int = let count_newlines (path: string): int =
let f file = In_channel.fold_lines file ~init:0 ~f:(fun i _ -> i + 1) in let f file = In_channel.fold_lines file ~init:0 ~f:(fun i _ -> i + 1) in
In_channel.with_file path ~f In_channel.with_file path ~f
@ -134,19 +136,22 @@ let create ?(warn_on_error=true) path =
from_abs_path ~warn_on_error path from_abs_path ~warn_on_error path
let changed_files_set = let changed_files_set =
Option.bind Config.changed_files_index Utils.read_file |> match Config.changed_files_index with
Option.map ~f:( | None ->
List.fold None
~f:(fun changed_files line -> | Some index -> match Utils.read_file index with
let source_file = create line in | Ok lines ->
let changed_files' = Set.add source_file changed_files in Some (List.fold lines ~init:Set.empty ~f:(fun changed_files line ->
(* Add source corresponding to changed header if it exists *) let source_file = create line in
match of_header source_file with let changed_files' = Set.add source_file changed_files in
| Some src -> Set.add src changed_files' (* Add source corresponding to changed header if it exists *)
| None -> changed_files' match of_header source_file with
) | Some src -> Set.add src changed_files'
~init:Set.empty | 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 =

@ -38,10 +38,10 @@ let read_file fname =
with with
| End_of_file -> | End_of_file ->
cleanup (); cleanup ();
Some (List.rev !res) Ok (List.rev !res)
| Sys_error _ -> | Sys_error error ->
cleanup (); cleanup ();
None Error error
(** copy a source file, return the number of lines, or None in case of error *) (** copy a source file, return the number of lines, or None in case of error *)
let copy_file fname_from fname_to = let copy_file fname_from fname_to =

@ -21,8 +21,8 @@ val string_crc_hex32 : string -> string
(** copy a source file, return the number of lines, or None in case of error *) (** copy a source file, return the number of lines, or None in case of error *)
val copy_file : string -> string -> int option val copy_file : string -> string -> int option
(** read a source file and return a list of lines, or None in case of error *) (** read a source file and return a list of lines *)
val read_file : string -> string list option val read_file : string -> (string list, string) Result.t
(** Convert a filename to an absolute one if it is relative, and normalize "." and ".." *) (** Convert a filename to an absolute one if it is relative, and normalize "." and ".." *)
val filename_to_absolute : root:string -> string -> string val filename_to_absolute : root:string -> string -> string

Loading…
Cancel
Save