123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120(********************************************************************************)(* crs - A tool for managing code review comments embedded in source code *)(* Copyright (C) 2024-2025 Mathieu Barbin <mathieu.barbin@gmail.com> *)(* *)(* This file is part of crs. *)(* *)(* crs is free software; you can redistribute it and/or modify it under the *)(* terms of the GNU Lesser General Public License as published by the Free *)(* Software Foundation either version 3 of the License, or any later version, *)(* with the LGPL-3.0 Linking Exception. *)(* *)(* crs is distributed in the hope that it will be useful, but WITHOUT ANY *)(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *)(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *)(* the file `NOTICE.md` at the root of this repository for more details. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* and the LGPL-3.0 Linking Exception along with this library. If not, see *)(* <http://www.gnu.org/licenses/> and <https://spdx.org>, respectively. *)(********************************************************************************)modulePath_display_mode=structtypet=|Absolute|Relative_to_repo_root|Relative_to_cwd[@@derivingenumerate]letto_string=function|Absolute->"absolute"|Relative_to_repo_root->"relative-to-repo-root"|Relative_to_cwd->"relative-to-cwd";;endletloc_to_stringloc~repo_root~below~path_display_mode=letloc=(Loc.to_lexbuf_locloc).startinletfname=Vcs.Path_in_repo.vloc.pos_fnameinletpath=match(path_display_mode:Path_display_mode.t)with|Absolute->(Vcs.Repo_root.appendrepo_rootfname|>Absolute_path.to_string)[@coverageoff]|Relative_to_cwd->(matchRelative_path.chop_prefix(Vcs.Path_in_repo.to_relative_pathfname)~prefix:belowwith|Somepath->Printf.sprintf"./%s"(Relative_path.to_stringpath)|None->Printf.sprintf"./%s"(Vcs.Path_in_repo.to_stringfname))|Relative_to_repo_root->Printf.sprintf"./%s"(Vcs.Path_in_repo.to_stringfname)inPrintf.sprintf"%s:%d:"pathloc.pos_lnum;;letto_stringt~repo_root~below~path_display_mode=String.concat~sep:"\n"[loc_to_string(Cr_comment.whole_loct)~repo_root~below~path_display_mode;Cr_comment.reindented_contentt;""];;letoutput_one~include_delimcr~oc~repo_root~below~path_display_mode=letstr=to_stringcr~repo_root~below~path_display_modeinletnl=ifinclude_delimthen"\n"else""inOut_channel.output_stringoc(Printf.sprintf"%s%s"nlstr);;letoutput_listcrs~oc~repo_root~below~path_display_mode=letcrs=Cr_comment.sortcrsinletinclude_delim=reffalseinList.itercrs~f:(funcr->output_one~include_delim:!include_delimcr~oc~repo_root~below~path_display_mode;include_delim:=true);;letmain=Command.make~summary:"A util used by the emacs crs-grep-mode."~readme:(fun()->{|
This command is a building block to the emacs $(b,crs-grep-mode).
It first locates the repository in which the command is launched and then grep-finds all CRs located in listed-files located in the subtree whose root is the current working directory of the command.
It then prints these CRs to $(b,stdout), displaying paths using a syntax that facilitate the integration with emacs grep-mode.
By default the file paths are displayed relative to the command's $(b,cwd).
|})(letopenCommand.Stdinlet+path_display_mode=Arg.named_with_default["path-display-mode"](Param.enumerated(modulePath_display_mode))~docv:"MODE"~doc:"Specify how the paths are displayed."~default:Relative_to_cwdand+filters=Common_helpers.filtersinletcwd=Unix.getcwd()|>Absolute_path.vinlet{Enclosing_repo.vcs_kind=_;repo_root;vcs}=Common_helpers.find_enclosing_repo~from:cwdinletbelow=Common_helpers.relativize~repo_root~cwd~path:(Relative_path.empty:>Fpath.t)inletcrs=letall_crs=Crs_parser.grep~vcs~repo_root~belowinmatchfilterswith|`Default->all_crs|`Suppliedfilters->List.filterall_crs~f:(funcr->List.existsfilters~f:(funfilter->Cr_comment.Filter.matchesfilter~cr))inoutput_listcrs~oc:Out_channel.stdout~repo_root~below:(Vcs.Path_in_repo.to_relative_pathbelow)~path_display_mode);;