##// END OF EJS Templates
hgignore: add a GlobSuffix type, instead of passing byte arrays...
Arseniy Alekseyev -
r53249:2ff004fb default
parent child Browse files
Show More
@@ -214,10 +214,33 lazy_static! {
214 214 static ref FLAG_RE: Regex = Regex::new(r"^\(\?[aiLmsux]+\)").unwrap();
215 215 }
216 216
217 /// Extra path components to match at the end of the pattern
218 #[derive(Clone, Copy)]
219 pub enum GlobSuffix {
220 /// `Empty` means the pattern only matches files, not directories,
221 /// so the path needs to match exactly.
222 Empty,
223 /// `MoreComponents` means the pattern matches directories as well,
224 /// so any path that has the pattern as a prefix, should match.
225 MoreComponents,
226 }
227
228 impl GlobSuffix {
229 fn to_re(self) -> &'static [u8] {
230 match self {
231 Self::Empty => b"$",
232 Self::MoreComponents => b"(?:/|$)",
233 }
234 }
235 }
236
217 237 /// Builds the regex that corresponds to the given pattern.
218 238 /// If within a `syntax: regexp` context, returns the pattern,
219 239 /// otherwise, returns the corresponding regex.
220 fn _build_single_regex(entry: &IgnorePattern, glob_suffix: &[u8]) -> Vec<u8> {
240 fn _build_single_regex(
241 entry: &IgnorePattern,
242 glob_suffix: GlobSuffix,
243 ) -> Vec<u8> {
221 244 let IgnorePattern {
222 245 syntax, pattern, ..
223 246 } = entry;
@@ -264,7 +287,11 fn _build_single_regex(entry: &IgnorePat
264 287 if pattern == b"." {
265 288 return vec![];
266 289 }
267 [escape_pattern(pattern).as_slice(), b"(?:/|$)"].concat()
290 [
291 escape_pattern(pattern).as_slice(),
292 GlobSuffix::MoreComponents.to_re(),
293 ]
294 .concat()
268 295 }
269 296 PatternSyntax::RootFilesIn => {
270 297 let mut res = if pattern == b"." {
@@ -281,13 +308,13 fn _build_single_regex(entry: &IgnorePat
281 308 PatternSyntax::RelGlob => {
282 309 let glob_re = glob_to_re(pattern);
283 310 if let Some(rest) = glob_re.drop_prefix(b"[^/]*") {
284 [b".*", rest, glob_suffix].concat()
311 [b".*", rest, glob_suffix.to_re()].concat()
285 312 } else {
286 [b"(?:.*/)?", glob_re.as_slice(), glob_suffix].concat()
313 [b"(?:.*/)?", glob_re.as_slice(), glob_suffix.to_re()].concat()
287 314 }
288 315 }
289 316 PatternSyntax::Glob | PatternSyntax::RootGlob => {
290 [glob_to_re(pattern).as_slice(), glob_suffix].concat()
317 [glob_to_re(pattern).as_slice(), glob_suffix.to_re()].concat()
291 318 }
292 319 PatternSyntax::Include
293 320 | PatternSyntax::SubInclude
@@ -345,7 +372,7 pub fn normalize_path_bytes(bytes: &[u8]
345 372 /// that don't need to be transformed into a regex.
346 373 pub fn build_single_regex(
347 374 entry: &IgnorePattern,
348 glob_suffix: &[u8],
375 glob_suffix: GlobSuffix,
349 376 ) -> Result<Option<Vec<u8>>, PatternError> {
350 377 let IgnorePattern {
351 378 pattern, syntax, ..
@@ -800,7 +827,7 mod tests {
800 827 b"rust/target/",
801 828 Path::new("")
802 829 ),
803 b"(?:/|$)"
830 GlobSuffix::MoreComponents
804 831 )
805 832 .unwrap(),
806 833 Some(br"(?:.*/)?rust/target(?:/|$)".to_vec()),
@@ -812,7 +839,7 mod tests {
812 839 br"rust/target/\d+",
813 840 Path::new("")
814 841 ),
815 b"(?:/|$)"
842 GlobSuffix::MoreComponents
816 843 )
817 844 .unwrap(),
818 845 Some(br"rust/target/\d+".to_vec()),
@@ -828,7 +855,7 mod tests {
828 855 b"",
829 856 Path::new("")
830 857 ),
831 b"(?:/|$)"
858 GlobSuffix::MoreComponents
832 859 )
833 860 .unwrap(),
834 861 None,
@@ -840,7 +867,7 mod tests {
840 867 b"whatever",
841 868 Path::new("")
842 869 ),
843 b"(?:/|$)"
870 GlobSuffix::MoreComponents
844 871 )
845 872 .unwrap(),
846 873 None,
@@ -852,7 +879,7 mod tests {
852 879 b"*.o",
853 880 Path::new("")
854 881 ),
855 b"(?:/|$)"
882 GlobSuffix::MoreComponents
856 883 )
857 884 .unwrap(),
858 885 Some(br"[^/]*\.o(?:/|$)".to_vec()),
@@ -868,7 +895,7 mod tests {
868 895 b"^ba{2}r",
869 896 Path::new("")
870 897 ),
871 b"(?:/|$)"
898 GlobSuffix::MoreComponents
872 899 )
873 900 .unwrap(),
874 901 Some(b"^ba{2}r".to_vec()),
@@ -880,7 +907,7 mod tests {
880 907 b"ba{2}r",
881 908 Path::new("")
882 909 ),
883 b"(?:/|$)"
910 GlobSuffix::MoreComponents
884 911 )
885 912 .unwrap(),
886 913 Some(b".*ba{2}r".to_vec()),
@@ -892,7 +919,7 mod tests {
892 919 b"(?ia)ba{2}r",
893 920 Path::new("")
894 921 ),
895 b"(?:/|$)"
922 GlobSuffix::MoreComponents
896 923 )
897 924 .unwrap(),
898 925 Some(b"(?ia:.*ba{2}r)".to_vec()),
@@ -904,7 +931,7 mod tests {
904 931 b"(?ia)^ba{2}r",
905 932 Path::new("")
906 933 ),
907 b"(?:/|$)"
934 GlobSuffix::MoreComponents
908 935 )
909 936 .unwrap(),
910 937 Some(b"(?ia:^ba{2}r)".to_vec()),
@@ -14,8 +14,8 use crate::{
14 14 dirstate::dirs_multiset::{DirsChildrenMultiset, DirsMultiset},
15 15 filepatterns::{
16 16 build_single_regex, filter_subincludes, get_patterns_from_file,
17 IgnorePattern, PatternError, PatternFileWarning, PatternResult,
18 PatternSyntax,
17 GlobSuffix, IgnorePattern, PatternError, PatternFileWarning,
18 PatternResult, PatternSyntax,
19 19 },
20 20 utils::{
21 21 files::{dir_ancestors, find_dirs},
@@ -328,7 +328,8 impl<'a> PatternMatcher<'a> {
328 328 let prefix = ignore_patterns.iter().all(|k| {
329 329 matches!(k.syntax, PatternSyntax::Path | PatternSyntax::RelPath)
330 330 });
331 let (patterns, match_fn) = build_match(ignore_patterns, b"$")?;
331 let (patterns, match_fn) =
332 build_match(ignore_patterns, GlobSuffix::Empty)?;
332 333
333 334 Ok(Self {
334 335 patterns,
@@ -807,7 +808,7 fn re_matcher(pattern: &[u8]) -> Pattern
807 808 /// said regex formed by the given ignore patterns.
808 809 fn build_regex_match<'a>(
809 810 ignore_patterns: &[IgnorePattern],
810 glob_suffix: &[u8],
811 glob_suffix: GlobSuffix,
811 812 ) -> PatternResult<(Vec<u8>, IgnoreFnType<'a>)> {
812 813 let mut regexps = vec![];
813 814 let mut exact_set = HashSet::new();
@@ -927,7 +928,7 fn roots_dirs_and_parents(
927 928 /// should be matched.
928 929 fn build_match<'a>(
929 930 ignore_patterns: Vec<IgnorePattern>,
930 glob_suffix: &[u8],
931 glob_suffix: GlobSuffix,
931 932 ) -> PatternResult<(Vec<u8>, IgnoreFnType<'a>)> {
932 933 let mut match_funcs: Vec<IgnoreFnType<'a>> = vec![];
933 934 // For debugging and printing
@@ -1067,7 +1068,8 impl<'a> IncludeMatcher<'a> {
1067 1068 let prefix = ignore_patterns.iter().all(|k| {
1068 1069 matches!(k.syntax, PatternSyntax::Path | PatternSyntax::RelPath)
1069 1070 });
1070 let (patterns, match_fn) = build_match(ignore_patterns, b"(?:/|$)")?;
1071 let (patterns, match_fn) =
1072 build_match(ignore_patterns, GlobSuffix::MoreComponents)?;
1071 1073
1072 1074 Ok(Self {
1073 1075 patterns,
General Comments 0
You need to be logged in to leave comments. Login now