1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
let main =
Command.make
~summary:"Grep for CRs in the repository tree."
~readme:(fun () ->
"This command searches for code review comments ($(b,CRs)) among all files under \
version control in the enclosing repository, and prints them to $(b,stdout).\n\n\
Supports both $(b,git) and $(b,hg) repositories.\n\n\
By default, all CRs from the root of the enclosing repository are selected, even \
if the command is run from a subdirectory. Use $(b,--below) to restrict the \
search to a specific path.\n\n\
All types of CRs are printed by default. You can restrict the selection using \
filtering flags such as $(b,--xcrs) or $(b,--soon). Supplying multiple filtering \
flags selects the union of all matching CRs (i.e., flags are combined with OR).")
(let open Command.Std in
let+ below =
Arg.named_opt
[ "below" ]
(Param.validated_string (module Fpath))
~docv:"PATH"
~doc:"Only search for CRs below the supplied path."
and+ sexp = Arg.flag [ "sexp" ] ~doc:"Print CRs as S-expressions on stdout."
and+ summary =
Arg.flag
[ "summary" ]
~doc:
"Print CR counts in summary tables instead of listing each CR. Not compatible \
with $(b,--sexp)."
and+ filters = Common_helpers.filters in
let () =
if sexp && summary
then
raise
(Err.E
(Err.create
~exit_code:Err.Exit_code.cli_error
Pp.O.
[ Pp.text "The flags "
++ Pp_tty.kwd (module String) "sexp"
++ Pp.text " and "
++ Pp_tty.kwd (module String) "summary"
++ Pp.text " are exclusive."
]
~hints:[ Pp.text "Please choose one." ] [@coverage off]))
in
let cwd = Unix.getcwd () |> Absolute_path.v in
let { Enclosing_repo.vcs_kind = _; repo_root; vcs } =
Common_helpers.find_enclosing_repo ~from:cwd
in
let below =
match below with
| None -> Vcs.Path_in_repo.root
| Some path -> Common_helpers.relativize ~repo_root ~cwd ~path
in
let () = Stdlib.Sys.set_signal Stdlib.Sys.sigpipe Stdlib.Sys.Signal_ignore in
let crs =
let all_crs = Crs_parser.grep ~vcs ~repo_root ~below in
let selected =
match filters with
| `All -> all_crs
| `Only filters ->
List.filter all_crs ~f:(fun cr ->
List.exists filters ~f:(fun filter -> Cr_comment.Filter.matches filter ~cr))
in
Cr_comment.sort selected
in
Git_pager.run ~f:(fun ->
let oc = Git_pager.write_end git_pager in
if sexp
then
Ref.set_temporarily Loc.include_sexp_of_locs true ~f:(fun () ->
List.iter crs ~f:(fun cr ->
Out_channel.output_line oc (Sexp.to_string_hum [%sexp (cr : Cr_comment.t)])))
else if summary
then (
let by_type =
Summary_table.By_type.make crs |> Summary_table.By_type.to_print_table
in
let summary = Summary_table.make crs |> Summary_table.to_print_table in
let tables =
List.filter_opt [ by_type; summary ]
|> List.map ~f:Print_table.to_string_text
|> String.concat ~sep:"\n"
in
Out_channel.output_string oc tables)
else Cr_comment.output_list crs ~oc))
;;