Skip to content

Commit

Permalink
Add silence support
Browse files Browse the repository at this point in the history
With this patch there is a newly supported section in `.flowconfig`:

```ini
[silence]
/path/to/file.js
/path/to/dir
```

Paths in `[silence]` will still be typechecked, but any
errors will be silenced as if there was a `suppress_comment` comment string
on every line where there are errors.

I called it `silence` to make it stand out from `ignore` and `suppress_comment` as
it currently silences all errors, including lints.

I believe this fixes #869, though I admit I didn't read
the whole issue.
  • Loading branch information
LegNeato committed Sep 22, 2017
1 parent 8708e4c commit 24936cb
Show file tree
Hide file tree
Showing 23 changed files with 179 additions and 37 deletions.
30 changes: 25 additions & 5 deletions src/commands/commandUtils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -290,18 +290,20 @@ type flowconfig_params = {
* can defer parsing of the lint settings until after the flowconfig lint settings
* are known, to properly detect redundant settings (and avoid false positives) *)
raw_lint_severities: string list;
silences: string list;
}

let list_of_string_arg = function
| None -> []
| Some arg_str -> Str.split (Str.regexp ",") arg_str

let collect_flowconfig_flags main ignores_str includes_str lib_str lints_str =
let collect_flowconfig_flags main ignores_str includes_str lib_str lints_str silence_str =
let ignores = list_of_string_arg ignores_str in
let includes = list_of_string_arg includes_str in
let libs = list_of_string_arg lib_str in
let raw_lint_severities = list_of_string_arg lints_str in
main { ignores; includes; libs; raw_lint_severities; }
let silences = list_of_string_arg silence_str in
main { ignores; includes; libs; raw_lint_severities; silences; }

let file_options =
let default_lib_dir ~no_flowlib tmp_dir =
Expand Down Expand Up @@ -331,6 +333,12 @@ let file_options =
Path_matcher.add acc path
) Path_matcher.empty paths
in
let silences_of_arg root paths =
List.fold_left (fun acc path ->
let path = Files.make_path_absolute root path in
Path_matcher.add acc path
) Path_matcher.empty paths
in
let lib_paths ~root flowconfig extras =
let flowtyped_path = Files.get_flowtyped_path root in
let has_explicit_flowtyped_lib = ref false in
Expand All @@ -355,7 +363,7 @@ let file_options =
| [] -> config_libs
| _ -> config_libs @ (List.map Path.make extras)
in
fun ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs flowconfig ->
fun ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~silences flowconfig ->
let default_lib_dir =
let no_flowlib = no_flowlib || FlowConfig.no_flowlib flowconfig in
Some (default_lib_dir ~no_flowlib temp_dir)
Expand All @@ -368,6 +376,10 @@ let file_options =
includes
|> List.rev_append (FlowConfig.includes flowconfig)
|> includes_of_arg root in
let silences =
silences
|> List.rev_append (FlowConfig.silences flowconfig)
|> silences_of_arg root in
{ Files.
default_lib_dir;
ignores;
Expand All @@ -376,6 +388,7 @@ let file_options =
module_file_exts = FlowConfig.module_file_exts flowconfig;
module_resource_exts = FlowConfig.module_resource_exts flowconfig;
node_resolver_dirnames = FlowConfig.node_resolver_dirnames flowconfig;
silences;
}

let ignore_flag prev = CommandSpec.ArgSpec.(
Expand All @@ -402,13 +415,20 @@ let lints_flag prev = CommandSpec.ArgSpec.(
~doc:"Specify one or more lint rules, comma separated"
)

let silence_flag prev = CommandSpec.ArgSpec.(
prev
|> flag "--silence" (optional string)
~doc:"Specify one or more files/directories to silence, comma separated"
)

let flowconfig_flags prev = CommandSpec.ArgSpec.(
prev
|> collect collect_flowconfig_flags
|> ignore_flag
|> include_flag
|> lib_flag
|> lints_flag
|> silence_flag
)

type command_params = {
Expand Down Expand Up @@ -579,8 +599,8 @@ let make_options ~flowconfig ~lazy_mode ~root (options_flags: Options_flags.t) =
let open Options_flags in
let file_options =
let no_flowlib = options_flags.no_flowlib in
let { includes; ignores; libs; raw_lint_severities=_; } = options_flags.flowconfig_flags in
file_options ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs flowconfig
let { includes; ignores; libs; raw_lint_severities=_; silences; } = options_flags.flowconfig_flags in
file_options ~root ~no_flowlib ~temp_dir ~includes ~ignores ~libs ~silences flowconfig
in
let lint_severities = parse_lints_flag
(FlowConfig.lint_severities flowconfig) options_flags.flowconfig_flags.raw_lint_severities
Expand Down
28 changes: 23 additions & 5 deletions src/commands/config/flowConfig.ml
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ type config = {
lint_severities: Severity.severity LintSettings.t;
(* config options *)
options: Opts.t;
(* non-root silence paths *)
silences: string list;
}

module Pp : sig
Expand Down Expand Up @@ -367,6 +369,9 @@ end = struct
(string_of_severity state)))
lint_severities

let silences o silences =
List.iter (fun silence -> (fprintf o "%s\n" silence)) silences

let config o config =
section_header o "ignore";
ignores o config.ignores;
Expand All @@ -381,15 +386,19 @@ end = struct
lints o config;
fprintf o "\n";
section_header o "options";
options o config
options o config;
fprintf o "\n";
section_header o "silence";
silences o config.silences
end

let empty_config = {
ignores = [];
includes = [];
libs = [];
lint_severities = LintSettings.default_severities;
options = Opts.default_options
options = Opts.default_options;
silences = []
}

let group_into_sections lines =
Expand Down Expand Up @@ -434,6 +443,10 @@ let parse_ignores config lines =
let ignores = trim_lines lines in
{ config with ignores; }

let parse_silences config lines =
let silences = trim_lines lines in
{ config with silences; }

let parse_options config lines =
let open Opts in
let (>>=) = Result.(>>=) in
Expand Down Expand Up @@ -869,6 +882,7 @@ let parse_section config ((section_ln, section), lines) =
| "libs", _ -> parse_libs config lines
| "lints", _ -> parse_lints config lines
| "options", _ -> parse_options config lines
| "silence", _ -> parse_silences config lines
| "version", _ -> parse_version config lines
| _ -> error section_ln (spf "Unsupported config section: \"%s\"" section)

Expand All @@ -894,17 +908,19 @@ let read filename =
|> List.filter is_not_comment in
parse empty_config lines

let init ~ignores ~includes ~libs ~options ~lints =
let init ~ignores ~includes ~libs ~lints ~options ~silences =
let ignores_lines = List.map (fun s -> (1, s)) ignores in
let includes_lines = List.map (fun s -> (1, s)) includes in
let options_lines = List.map (fun s -> (1, s)) options in
let lib_lines = List.map (fun s -> (1, s)) libs in
let lint_lines = List.map (fun s -> (1, s)) lints in
let options_lines = List.map (fun s -> (1, s)) options in
let silences_lines = List.map (fun s -> (1, s)) silences in
let config = parse_ignores empty_config ignores_lines in
let config = parse_includes config includes_lines in
let config = parse_options config options_lines in
let config = parse_libs config lib_lines in
let config = parse_lints config lint_lines in
let config = parse_options config options_lines in
let config = parse_silences config silences_lines in
config

let write config oc = Pp.config oc config
Expand Down Expand Up @@ -933,6 +949,8 @@ let ignores config = config.ignores
let includes config = config.includes
(* library paths. no wildcards *)
let libs config = config.libs
(* silence paths. no wildcards *)
let silences config = config.silences

(* options *)
let all c = c.options.Opts.all
Expand Down
5 changes: 4 additions & 1 deletion src/commands/config/flowConfig.mli
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ val init:
ignores: string list ->
includes: string list ->
libs: string list ->
options: string list ->
lints: string list ->
options: string list ->
silences: string list ->
config
val write: config -> out_channel -> unit

Expand All @@ -32,6 +33,8 @@ val ignores: config -> string list
val includes: config -> string list
(* library paths. no wildcards *)
val libs: config -> string list
(* non-root paths to silence *)
val silences: config -> string list

(* options *)
val all: config -> bool
Expand Down
3 changes: 2 additions & 1 deletion src/commands/configCommands.ml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module Init = struct
let includes = flowconfig_flags.CommandUtils.includes in
let libs = flowconfig_flags.CommandUtils.libs in
let lints = flowconfig_flags.CommandUtils.raw_lint_severities in
let silences = flowconfig_flags.CommandUtils.silences in

let file = Server_files_js.config_file root in
if Sys.file_exists file
Expand All @@ -51,7 +52,7 @@ module Init = struct
FlowExitStatus.(exit ~msg Invalid_flowconfig)
end;

let config = FlowConfig.init ~ignores ~includes ~libs ~options ~lints in
let config = FlowConfig.init ~ignores ~includes ~libs ~lints ~options ~silences in

let out = Sys_utils.open_out_no_fail file in
FlowConfig.write config out;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/genFlowFilesCommand.ml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ let main option_values root error_flags strip_root ignore_flag
FlowExitStatus.exit ~msg FlowExitStatus.Commandline_usage_error
);

let options = LsCommand.make_options ~root ~ignore_flag ~include_flag in
let options = LsCommand.make_options ~root ~ignore_flag ~include_flag ~silence_flag:None in
let _, libs = Files.init options in
let next_files =
LsCommand.get_ls_files ~root ~all:false ~options ~libs ~imaginary:false (Some src)
Expand Down
10 changes: 6 additions & 4 deletions src/commands/lsCommand.ml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ let spec = {
|> ignore_flag
|> include_flag
|> root_flag
|> silence_flag
|> json_flags
|> from_flag
|> flag "--all" no_arg
Expand Down Expand Up @@ -106,13 +107,14 @@ let rec iter_get_next ~f get_next =
List.iter f result;
iter_get_next ~f get_next

let make_options ~root ~ignore_flag ~include_flag =
let make_options ~root ~ignore_flag ~include_flag ~silence_flag =
let flowconfig = FlowConfig.get (Server_files_js.config_file root) in
let temp_dir = FlowConfig.temp_dir flowconfig in
let includes = CommandUtils.list_of_string_arg include_flag in
let ignores = CommandUtils.list_of_string_arg ignore_flag in
let libs = [] in
CommandUtils.file_options ~root ~no_flowlib:true ~temp_dir ~ignores ~includes ~libs flowconfig
let silences = CommandUtils.list_of_string_arg silence_flag in
CommandUtils.file_options ~root ~no_flowlib:true ~temp_dir ~ignores ~includes ~libs ~silences flowconfig

(* Directories will return a closure that returns every file under that
directory. Individual files will return a closure that returns just that file
Expand Down Expand Up @@ -152,7 +154,7 @@ let concat_get_next get_nexts =
in concat

let main
strip_root ignore_flag include_flag root_flag json pretty from all imaginary reason
strip_root ignore_flag include_flag root_flag silence_flag json pretty from all imaginary reason
input_file root_or_files () =

let files_or_dirs = get_filenames_from_input ~allow_imaginary:true input_file root_or_files in
Expand All @@ -172,7 +174,7 @@ let main
| _ -> None)
) in

let options = make_options ~root ~ignore_flag ~include_flag in
let options = make_options ~root ~ignore_flag ~include_flag ~silence_flag in
let _, libs = Files.init options in
(* `flow ls` and `flow ls dir` will list out all the flow files *)
let next_files = (match files_or_dirs with
Expand Down
6 changes: 6 additions & 0 deletions src/common/files.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type options = {
module_file_exts: SSet.t;
module_resource_exts: SSet.t;
node_resolver_dirnames: string list;
silences: Path_matcher.t;
}

let default_lib_dir options = options.default_lib_dir
Expand All @@ -27,6 +28,7 @@ let lib_paths options = options.lib_paths
let module_file_exts options = options.module_file_exts
let module_resource_exts options = options.module_resource_exts
let node_resolver_dirnames options = options.node_resolver_dirnames
let silences options = options.silences

let node_modules_containers = ref SSet.empty

Expand Down Expand Up @@ -296,6 +298,10 @@ let is_ignored (options: options) =
let is_included options f =
Path_matcher.matches options.includes f

(* true if a file path matches a [silence] path in config *)
let is_silenced options f =
Path_matcher.matches options.silences f

let wanted ~options lib_fileset =
let is_ignored_ = is_ignored options in
fun path -> not (is_ignored_ path) && not (SSet.mem path lib_fileset)
Expand Down
4 changes: 4 additions & 0 deletions src/common/files.mli
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type options = {
module_file_exts: SSet.t;
module_resource_exts: SSet.t;
node_resolver_dirnames: string list;
silences: Path_matcher.t;
}

val default_lib_dir: options -> Path.t option
Expand All @@ -27,6 +28,7 @@ val lib_paths: options -> Path.t list
val module_file_exts: options -> SSet.t
val module_resource_exts: options -> SSet.t
val node_resolver_dirnames: options -> string list
val silences: options -> Path_matcher.t

val node_modules_containers: SSet.t ref

Expand All @@ -43,6 +45,8 @@ val is_flow_file: options: options -> string -> bool
val is_ignored: options -> string -> bool
(* true if a file path matches an [include] path in config *)
val is_included: options -> string -> bool
(* true if a file path matches a [silence] path in config *)
val is_silenced: options -> string -> bool

val is_valid_path: options: options -> string -> bool

Expand Down
4 changes: 2 additions & 2 deletions src/flow_dot_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ let load_lib_files ~master_cx ~metadata files
match parse_content lib_file lib_content with
| ast, [] ->
let cx, syms = Type_inference_js.infer_lib_file
~metadata ~exclude_syms ~lint_severities:None
~metadata ~exclude_syms ~file_options:None ~lint_severities:None
lib_file ast
in

Expand Down Expand Up @@ -168,7 +168,7 @@ let infer_and_merge ~root filename ast =
let reqs = Merge_js.Reqs.({ empty with decls }) in
let file_sigs = Utils_js.FilenameMap.singleton filename file_sig in
Merge_js.merge_component_strict
~metadata ~lint_severities:None ~file_sigs
~metadata ~file_options:None ~lint_severities:None ~file_sigs
~get_ast_unsafe:(fun _ -> ast)
~get_docblock_unsafe:(fun _ -> stub_docblock)
[filename] reqs [] master_cx
Expand Down
3 changes: 2 additions & 1 deletion src/services/inference/init_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ let load_lib_files ~master_cx ~options files =

let lib_file = Loc.LibFile file in
let lint_severities = options.Options.opt_lint_severities in
let file_options = Options.file_options options in
match parse_lib_file options file with
| Parsing.Parse_ok ast ->

Expand All @@ -85,7 +86,7 @@ let load_lib_files ~master_cx ~options files =
in

let cx, syms = Infer.infer_lib_file
~metadata ~exclude_syms ~lint_severities:(Some lint_severities)
~metadata ~exclude_syms ~file_options:(Some file_options) ~lint_severities:(Some lint_severities)
lib_file ast
in

Expand Down
6 changes: 4 additions & 2 deletions src/services/inference/merge_service.ml
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,10 @@ let merge_strict_context ~options component =
in

let metadata = Context.metadata_of_options options in
let file_options = Some (Options.file_options options) in
let lint_severities = Some (Options.lint_severities options) in
let cx = Merge_js.merge_component_strict
~metadata ~lint_severities ~file_sigs
~metadata ~lint_severities ~file_options ~file_sigs
~get_ast_unsafe:Parsing_service_js.get_ast_unsafe
~get_docblock_unsafe:Parsing_service_js.get_docblock_unsafe
component file_reqs dep_cxs master_cx
Expand Down Expand Up @@ -136,8 +137,9 @@ let merge_contents_context options file ast info ~ensure_checked_dependencies =

let metadata = Context.metadata_of_options options in
let lint_severities = Some (Options.lint_severities options) in
let file_options = Some (Options.file_options options) in
let cx = Merge_js.merge_component_strict
~metadata ~lint_severities ~file_sigs
~metadata ~file_options ~lint_severities ~file_sigs
~get_ast_unsafe:(fun _ -> ast)
~get_docblock_unsafe:(fun _ -> info)
component file_reqs dep_cxs master_cx
Expand Down
Loading

0 comments on commit 24936cb

Please sign in to comment.