Mercurial > hg-stable
changeset 48403:6d4daf51283c
rhg: implement the debugignorerhg subcommand
This can be used to inspect the generated pattern, but also to benchmark
the time it takes to parse hgignore.
Differential Revision: https://phab.mercurial-scm.org/D11722
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Mon, 29 Nov 2021 14:07:47 +0000 |
parents | 2009e3c64a53 |
children | 8ec4e8d7bbe6 |
files | rust/hg-core/src/matchers.rs rust/rhg/src/commands/debugignorerhg.rs rust/rhg/src/main.rs |
diffstat | 3 files changed, 66 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/matchers.rs Mon Nov 29 14:06:41 2021 +0000 +++ b/rust/hg-core/src/matchers.rs Mon Nov 29 14:07:47 2021 +0000 @@ -561,11 +561,11 @@ /// Parses all "ignore" files with their recursive includes and returns a /// function that checks whether a given file (in the general sense) should be /// ignored. -pub fn get_ignore_function<'a>( +pub fn get_ignore_matcher<'a>( mut all_pattern_files: Vec<PathBuf>, root_dir: &Path, inspect_pattern_bytes: &mut impl FnMut(&[u8]), -) -> PatternResult<(IgnoreFnType<'a>, Vec<PatternFileWarning>)> { +) -> PatternResult<(IncludeMatcher<'a>, Vec<PatternFileWarning>)> { let mut all_patterns = vec![]; let mut all_warnings = vec![]; @@ -588,10 +588,25 @@ all_warnings.extend(warnings); } let matcher = IncludeMatcher::new(all_patterns)?; - Ok(( - Box::new(move |path: &HgPath| matcher.matches(path)), - all_warnings, - )) + Ok((matcher, all_warnings)) +} + +/// Parses all "ignore" files with their recursive includes and returns a +/// function that checks whether a given file (in the general sense) should be +/// ignored. +pub fn get_ignore_function<'a>( + all_pattern_files: Vec<PathBuf>, + root_dir: &Path, + inspect_pattern_bytes: &mut impl FnMut(&[u8]), +) -> PatternResult<(IgnoreFnType<'a>, Vec<PatternFileWarning>)> { + let res = + get_ignore_matcher(all_pattern_files, root_dir, inspect_pattern_bytes); + res.map(|(matcher, all_warnings)| { + let res: IgnoreFnType<'a> = + Box::new(move |path: &HgPath| matcher.matches(path)); + + (res, all_warnings) + }) } impl<'a> IncludeMatcher<'a> { @@ -626,6 +641,10 @@ .chain(self.parents.iter()); DirsChildrenMultiset::new(thing, Some(&self.parents)) } + + pub fn debug_get_patterns(&self) -> &[u8] { + self.patterns.as_ref() + } } impl<'a> Display for IncludeMatcher<'a> {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/rhg/src/commands/debugignorerhg.rs Mon Nov 29 14:07:47 2021 +0000 @@ -0,0 +1,40 @@ +use crate::error::CommandError; +use clap::SubCommand; +use hg; +use hg::matchers::get_ignore_matcher; +use hg::StatusError; +use log::warn; + +pub const HELP_TEXT: &str = " +Show effective hgignore patterns used by rhg. + +This is a pure Rust version of `hg debugignore`. + +Some options might be missing, check the list below. +"; + +pub fn args() -> clap::App<'static, 'static> { + SubCommand::with_name("debugignorerhg").about(HELP_TEXT) +} + +pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> { + let repo = invocation.repo?; + + let ignore_file = repo.working_directory_vfs().join(".hgignore"); // TODO hardcoded + + let (ignore_matcher, warnings) = get_ignore_matcher( + vec![ignore_file], + &repo.working_directory_path().to_owned(), + &mut |_pattern_bytes| (), + ) + .map_err(|e| StatusError::from(e))?; + + if !warnings.is_empty() { + warn!("Pattern warnings: {:?}", &warnings); + } + + let patterns = ignore_matcher.debug_get_patterns(); + invocation.ui.write_stdout(patterns)?; + invocation.ui.write_stdout(b"\n")?; + Ok(()) +}