##// 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 static ref FLAG_RE: Regex = Regex::new(r"^\(\?[aiLmsux]+\)").unwrap();
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 /// Builds the regex that corresponds to the given pattern.
237 /// Builds the regex that corresponds to the given pattern.
218 /// If within a `syntax: regexp` context, returns the pattern,
238 /// If within a `syntax: regexp` context, returns the pattern,
219 /// otherwise, returns the corresponding regex.
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 let IgnorePattern {
244 let IgnorePattern {
222 syntax, pattern, ..
245 syntax, pattern, ..
223 } = entry;
246 } = entry;
@@ -264,7 +287,11 fn _build_single_regex(entry: &IgnorePat
264 if pattern == b"." {
287 if pattern == b"." {
265 return vec![];
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 PatternSyntax::RootFilesIn => {
296 PatternSyntax::RootFilesIn => {
270 let mut res = if pattern == b"." {
297 let mut res = if pattern == b"." {
@@ -281,13 +308,13 fn _build_single_regex(entry: &IgnorePat
281 PatternSyntax::RelGlob => {
308 PatternSyntax::RelGlob => {
282 let glob_re = glob_to_re(pattern);
309 let glob_re = glob_to_re(pattern);
283 if let Some(rest) = glob_re.drop_prefix(b"[^/]*") {
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 } else {
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 PatternSyntax::Glob | PatternSyntax::RootGlob => {
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 PatternSyntax::Include
319 PatternSyntax::Include
293 | PatternSyntax::SubInclude
320 | PatternSyntax::SubInclude
@@ -345,7 +372,7 pub fn normalize_path_bytes(bytes: &[u8]
345 /// that don't need to be transformed into a regex.
372 /// that don't need to be transformed into a regex.
346 pub fn build_single_regex(
373 pub fn build_single_regex(
347 entry: &IgnorePattern,
374 entry: &IgnorePattern,
348 glob_suffix: &[u8],
375 glob_suffix: GlobSuffix,
349 ) -> Result<Option<Vec<u8>>, PatternError> {
376 ) -> Result<Option<Vec<u8>>, PatternError> {
350 let IgnorePattern {
377 let IgnorePattern {
351 pattern, syntax, ..
378 pattern, syntax, ..
@@ -800,7 +827,7 mod tests {
800 b"rust/target/",
827 b"rust/target/",
801 Path::new("")
828 Path::new("")
802 ),
829 ),
803 b"(?:/|$)"
830 GlobSuffix::MoreComponents
804 )
831 )
805 .unwrap(),
832 .unwrap(),
806 Some(br"(?:.*/)?rust/target(?:/|$)".to_vec()),
833 Some(br"(?:.*/)?rust/target(?:/|$)".to_vec()),
@@ -812,7 +839,7 mod tests {
812 br"rust/target/\d+",
839 br"rust/target/\d+",
813 Path::new("")
840 Path::new("")
814 ),
841 ),
815 b"(?:/|$)"
842 GlobSuffix::MoreComponents
816 )
843 )
817 .unwrap(),
844 .unwrap(),
818 Some(br"rust/target/\d+".to_vec()),
845 Some(br"rust/target/\d+".to_vec()),
@@ -828,7 +855,7 mod tests {
828 b"",
855 b"",
829 Path::new("")
856 Path::new("")
830 ),
857 ),
831 b"(?:/|$)"
858 GlobSuffix::MoreComponents
832 )
859 )
833 .unwrap(),
860 .unwrap(),
834 None,
861 None,
@@ -840,7 +867,7 mod tests {
840 b"whatever",
867 b"whatever",
841 Path::new("")
868 Path::new("")
842 ),
869 ),
843 b"(?:/|$)"
870 GlobSuffix::MoreComponents
844 )
871 )
845 .unwrap(),
872 .unwrap(),
846 None,
873 None,
@@ -852,7 +879,7 mod tests {
852 b"*.o",
879 b"*.o",
853 Path::new("")
880 Path::new("")
854 ),
881 ),
855 b"(?:/|$)"
882 GlobSuffix::MoreComponents
856 )
883 )
857 .unwrap(),
884 .unwrap(),
858 Some(br"[^/]*\.o(?:/|$)".to_vec()),
885 Some(br"[^/]*\.o(?:/|$)".to_vec()),
@@ -868,7 +895,7 mod tests {
868 b"^ba{2}r",
895 b"^ba{2}r",
869 Path::new("")
896 Path::new("")
870 ),
897 ),
871 b"(?:/|$)"
898 GlobSuffix::MoreComponents
872 )
899 )
873 .unwrap(),
900 .unwrap(),
874 Some(b"^ba{2}r".to_vec()),
901 Some(b"^ba{2}r".to_vec()),
@@ -880,7 +907,7 mod tests {
880 b"ba{2}r",
907 b"ba{2}r",
881 Path::new("")
908 Path::new("")
882 ),
909 ),
883 b"(?:/|$)"
910 GlobSuffix::MoreComponents
884 )
911 )
885 .unwrap(),
912 .unwrap(),
886 Some(b".*ba{2}r".to_vec()),
913 Some(b".*ba{2}r".to_vec()),
@@ -892,7 +919,7 mod tests {
892 b"(?ia)ba{2}r",
919 b"(?ia)ba{2}r",
893 Path::new("")
920 Path::new("")
894 ),
921 ),
895 b"(?:/|$)"
922 GlobSuffix::MoreComponents
896 )
923 )
897 .unwrap(),
924 .unwrap(),
898 Some(b"(?ia:.*ba{2}r)".to_vec()),
925 Some(b"(?ia:.*ba{2}r)".to_vec()),
@@ -904,7 +931,7 mod tests {
904 b"(?ia)^ba{2}r",
931 b"(?ia)^ba{2}r",
905 Path::new("")
932 Path::new("")
906 ),
933 ),
907 b"(?:/|$)"
934 GlobSuffix::MoreComponents
908 )
935 )
909 .unwrap(),
936 .unwrap(),
910 Some(b"(?ia:^ba{2}r)".to_vec()),
937 Some(b"(?ia:^ba{2}r)".to_vec()),
@@ -14,8 +14,8 use crate::{
14 dirstate::dirs_multiset::{DirsChildrenMultiset, DirsMultiset},
14 dirstate::dirs_multiset::{DirsChildrenMultiset, DirsMultiset},
15 filepatterns::{
15 filepatterns::{
16 build_single_regex, filter_subincludes, get_patterns_from_file,
16 build_single_regex, filter_subincludes, get_patterns_from_file,
17 IgnorePattern, PatternError, PatternFileWarning, PatternResult,
17 GlobSuffix, IgnorePattern, PatternError, PatternFileWarning,
18 PatternSyntax,
18 PatternResult, PatternSyntax,
19 },
19 },
20 utils::{
20 utils::{
21 files::{dir_ancestors, find_dirs},
21 files::{dir_ancestors, find_dirs},
@@ -328,7 +328,8 impl<'a> PatternMatcher<'a> {
328 let prefix = ignore_patterns.iter().all(|k| {
328 let prefix = ignore_patterns.iter().all(|k| {
329 matches!(k.syntax, PatternSyntax::Path | PatternSyntax::RelPath)
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 Ok(Self {
334 Ok(Self {
334 patterns,
335 patterns,
@@ -807,7 +808,7 fn re_matcher(pattern: &[u8]) -> Pattern
807 /// said regex formed by the given ignore patterns.
808 /// said regex formed by the given ignore patterns.
808 fn build_regex_match<'a>(
809 fn build_regex_match<'a>(
809 ignore_patterns: &[IgnorePattern],
810 ignore_patterns: &[IgnorePattern],
810 glob_suffix: &[u8],
811 glob_suffix: GlobSuffix,
811 ) -> PatternResult<(Vec<u8>, IgnoreFnType<'a>)> {
812 ) -> PatternResult<(Vec<u8>, IgnoreFnType<'a>)> {
812 let mut regexps = vec![];
813 let mut regexps = vec![];
813 let mut exact_set = HashSet::new();
814 let mut exact_set = HashSet::new();
@@ -927,7 +928,7 fn roots_dirs_and_parents(
927 /// should be matched.
928 /// should be matched.
928 fn build_match<'a>(
929 fn build_match<'a>(
929 ignore_patterns: Vec<IgnorePattern>,
930 ignore_patterns: Vec<IgnorePattern>,
930 glob_suffix: &[u8],
931 glob_suffix: GlobSuffix,
931 ) -> PatternResult<(Vec<u8>, IgnoreFnType<'a>)> {
932 ) -> PatternResult<(Vec<u8>, IgnoreFnType<'a>)> {
932 let mut match_funcs: Vec<IgnoreFnType<'a>> = vec![];
933 let mut match_funcs: Vec<IgnoreFnType<'a>> = vec![];
933 // For debugging and printing
934 // For debugging and printing
@@ -1067,7 +1068,8 impl<'a> IncludeMatcher<'a> {
1067 let prefix = ignore_patterns.iter().all(|k| {
1068 let prefix = ignore_patterns.iter().all(|k| {
1068 matches!(k.syntax, PatternSyntax::Path | PatternSyntax::RelPath)
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 Ok(Self {
1074 Ok(Self {
1073 patterns,
1075 patterns,
General Comments 0
You need to be logged in to leave comments. Login now