mirror of
https://github.com/comby-tools/comby.git
synced 2024-09-11 13:25:36 +03:00
add rg option for filtering
This commit is contained in:
parent
3676531078
commit
872ca91ba5
@ -226,6 +226,8 @@ type user_input_options =
|
||||
; exclude_file_prefix : string list
|
||||
; custom_matcher : string option
|
||||
; override_matcher : string option
|
||||
; regex_pattern : bool
|
||||
; ripgrep_args : string option
|
||||
}
|
||||
|
||||
type run_options =
|
||||
@ -646,6 +648,26 @@ let select_matcher custom_matcher override_matcher file_filters omega =
|
||||
else
|
||||
of_extension engine file_filters
|
||||
|
||||
let regex_of_specifications specifications =
|
||||
Format.sprintf "(%s)"
|
||||
@@ String.concat ~sep:")|("
|
||||
@@ List.map specifications ~f:Specification.to_regex
|
||||
|
||||
let ripgrep_file_filters specifications args : string list =
|
||||
let regex = regex_of_specifications specifications in
|
||||
let args =
|
||||
String.split_on_chars args ~on:[' '; '\t'; '\r'; '\n']
|
||||
|> List.filter ~f:(String.(<>) "")
|
||||
in
|
||||
let result = Ripgrep.run ~pattern:regex ~args in
|
||||
match result with
|
||||
| Ok result ->
|
||||
if debug then Format.printf "Ripgrep result: %s@." @@ String.concat ~sep:"\n" result;
|
||||
result
|
||||
| Error e ->
|
||||
Format.eprintf "%s@." (Error.to_string_hum e);
|
||||
exit 1
|
||||
|
||||
let create
|
||||
({ input_options =
|
||||
{ rule
|
||||
@ -661,6 +683,8 @@ let create
|
||||
; exclude_file_prefix
|
||||
; custom_matcher
|
||||
; override_matcher
|
||||
; regex_pattern
|
||||
; ripgrep_args
|
||||
}
|
||||
; run_options =
|
||||
{ sequential
|
||||
@ -705,7 +729,8 @@ let create
|
||||
parse_templates ~warn_for_missing_file_in_dir:true omega templates
|
||||
| _ -> assert false
|
||||
in
|
||||
let file_filters =
|
||||
if regex_pattern then (Format.printf "%s@." (regex_of_specifications specifications); exit 0);
|
||||
let file_filters_from_anonymous_args =
|
||||
match anonymous_arguments with
|
||||
| None -> file_filters
|
||||
| Some { file_filters = None; _ } -> file_filters
|
||||
@ -716,6 +741,11 @@ let create
|
||||
| None ->
|
||||
Some anonymous_file_filters
|
||||
in
|
||||
let file_filters =
|
||||
match ripgrep_args with
|
||||
| Some args -> Some (ripgrep_file_filters specifications args)
|
||||
| None -> file_filters_from_anonymous_args
|
||||
in
|
||||
let input_source =
|
||||
match stdin, zip_file with
|
||||
| true, _ -> Stdin
|
||||
|
@ -53,6 +53,8 @@ type user_input_options =
|
||||
; exclude_file_prefix : string list
|
||||
; custom_matcher : string option
|
||||
; override_matcher : string option
|
||||
; regex_pattern : bool
|
||||
; ripgrep_args : string option
|
||||
}
|
||||
|
||||
type run_options =
|
||||
|
@ -2,4 +2,4 @@
|
||||
(name configuration)
|
||||
(public_name comby.configuration)
|
||||
(preprocess (pps ppx_deriving.show ppx_sexp_conv ppx_sexp_message ppx_deriving_yojson bisect_ppx --conditional))
|
||||
(libraries camlzip comby.statistics comby.parsers comby.match comby.language ppxlib core core.uuid mparser mparser.pcre yojson ppx_deriving_yojson hack_parallel toml))
|
||||
(libraries camlzip comby.statistics comby.parsers comby.match comby.language ppxlib core core.uuid mparser mparser.pcre yojson ppx_deriving_yojson hack_parallel toml re2 lwt lwt.unix))
|
||||
|
27
lib/configuration/ripgrep.ml
Normal file
27
lib/configuration/ripgrep.ml
Normal file
@ -0,0 +1,27 @@
|
||||
open Core
|
||||
open Lwt
|
||||
|
||||
let debug =
|
||||
Sys.getenv "DEBUG_COMBY"
|
||||
|> Option.is_some
|
||||
|
||||
let run ~pattern ~args =
|
||||
let options = ["--files-with-matches"; "--multiline"] in
|
||||
let pattern = Format.sprintf {|'%s'|} pattern in
|
||||
let command = ("rg" :: options @ args @ [pattern]) |> String.concat ~sep:" " in
|
||||
if debug then Format.printf "Executing: %s@." command;
|
||||
let lwt_command = Lwt_process.shell command in
|
||||
let recv proc =
|
||||
let ic = proc#stdout in
|
||||
Lwt.finalize
|
||||
(fun () -> Lwt_io.read ic)
|
||||
(fun () -> Lwt_io.close ic)
|
||||
in
|
||||
let f () =
|
||||
Lwt_process.with_process_in lwt_command (fun proc ->
|
||||
recv proc >>= fun result ->
|
||||
proc#status >>= function
|
||||
| WEXITED v when v <> 0 -> return @@ Or_error.errorf "Error executing rg, exit status %d." v
|
||||
| _ -> return (Ok (String.split ~on:'\n' result |> List.filter ~f:(String.(<>) ""))))
|
||||
in
|
||||
try Lwt_main.run (f ()) with Sys.Break -> exit 0
|
6
lib/configuration/ripgrep.mli
Normal file
6
lib/configuration/ripgrep.mli
Normal file
@ -0,0 +1,6 @@
|
||||
open Core
|
||||
|
||||
(* [run pattern args] accepts a [pattern] and list of extra ripgrep-compatible
|
||||
arguments [args], for example, ["-g"; "*.go"; "-g"; "*.ts"]. Returns a list
|
||||
of files if the commands succeeds. *)
|
||||
val run : pattern:string -> args:string list -> string list Or_error.t
|
@ -1,3 +1,5 @@
|
||||
open Core
|
||||
|
||||
open Language
|
||||
|
||||
type t =
|
||||
@ -6,5 +8,37 @@ type t =
|
||||
; rewrite_template : string option
|
||||
}
|
||||
|
||||
let escape s =
|
||||
let rec aux chars =
|
||||
match chars with
|
||||
| [] -> []
|
||||
| x :: xs ->
|
||||
match x with
|
||||
| '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' as c ->
|
||||
'\\' :: c :: (aux xs)
|
||||
| c -> c :: (aux xs)
|
||||
in
|
||||
aux (String.to_list s)
|
||||
|> String.of_char_list
|
||||
|
||||
let to_regex { match_template; _ } =
|
||||
let word_pattern = {|\w+|} in
|
||||
let hole_patterns =
|
||||
[ {|(:\[|} ^ word_pattern ^ {|\])|}
|
||||
; {|(:\[\[|} ^ word_pattern ^ {|\]\])|}
|
||||
; {|(:\[|} ^ word_pattern ^ {|\.\])|}
|
||||
; {|(:\[|} ^ word_pattern ^ {|\\n\])|}
|
||||
; {|(:\[|} ^ {|[ ]+(|} ^ word_pattern ^ {|)|} ^ {|\])|}
|
||||
]
|
||||
in
|
||||
let regexes = String.concat ~sep:"|" hole_patterns in
|
||||
let spaces = Re2.create_exn {|\s+|} in
|
||||
let m = Re2.split (Re2.create_exn regexes) match_template in
|
||||
(* Escape regex metachars *)
|
||||
let m = List.map m ~f:escape in
|
||||
(* Replace contiguous spaces with the regex \s+ *)
|
||||
let m = List.map m ~f:(fun split -> Re2.replace_exn ~f:(fun _ -> {|\s+|}) spaces split) in
|
||||
Format.sprintf "(%s)" @@ String.concat m ~sep:")(?s:.)*?("
|
||||
|
||||
let create ?rewrite_template ?rule ~match_template () =
|
||||
{ match_template; rule; rewrite_template }
|
||||
|
@ -103,6 +103,8 @@ let base_command_parameters : (unit -> 'result) Command.Param.t =
|
||||
and disable_substring_matching = flag "disable-substring-matching" no_arg ~doc:"Allow :[holes] to match substrings"
|
||||
and omega = flag "omega" no_arg ~doc:"Use Omega matcher engine."
|
||||
and fast_offset_conversion = flag "fast-offset-conversion" no_arg ~doc:"Enable fast offset conversion. This is experimental and will become the default once vetted."
|
||||
and regex_pattern = flag "regex" no_arg ~doc:"print a regex that a file must satisfy in order for a pattern to be run"
|
||||
and ripgrep_args = flag "ripgrep" (optional string) ~aliases:["rg"] ~doc:"flags Activate ripgrep for filtering files. Add flags like '-g *.go' to include or exclude file extensions."
|
||||
and anonymous_arguments =
|
||||
anon
|
||||
(maybe
|
||||
@ -187,6 +189,8 @@ let base_command_parameters : (unit -> 'result) Command.Param.t =
|
||||
; exclude_file_prefix
|
||||
; custom_matcher
|
||||
; override_matcher
|
||||
; regex_pattern
|
||||
; ripgrep_args
|
||||
}
|
||||
; run_options =
|
||||
{ sequential
|
||||
|
Loading…
Reference in New Issue
Block a user