Skip to content

Commit e9d222a

Browse files
committed
Support for 'ends_with' matching mode (#301)
1 parent 6a37eee commit e9d222a

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

git-attributes/src/ignore.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub mod pattern {
55
pub struct Mode: u32 {
66
/// The pattern does not contain a sub-directory and - it doesn't contain slashes after removing the trailing one.
77
const NO_SUB_DIR = 1 << 0;
8-
// TODO: find a much better name!
8+
/// A pattern that is '*literal', meaning that it ends with what's given here
99
const ENDS_WITH = 1 << 1;
1010
/// The pattern must match a directory, and not a file.
1111
const MUST_BE_DIR = 1 << 2;

git-attributes/src/parse/ignore.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl<'a> Iterator for Iter<'a> {
2424
}
2525
let mut lines = self.cursor.lines_with_terminator();
2626
let mut res = None;
27-
let mut offset = 0;
27+
let mut offset = 0; // TODO: prefer `lines()` with `into_bytes()` instead.
2828
for mut line in lines.by_ref() {
2929
self.line_no += 1;
3030
offset += line.len();
@@ -52,6 +52,9 @@ impl<'a> Iterator for Iter<'a> {
5252
if !line.contains(&b'/') {
5353
mode |= ignore::pattern::Mode::NO_SUB_DIR;
5454
}
55+
if line.first() == Some(&b'*') && line[1..].find_byteset(br"*?[\").is_none() {
56+
mode |= ignore::pattern::Mode::ENDS_WITH;
57+
}
5558
res = Some((line, mode, self.line_no));
5659
break;
5760
}

git-attributes/tests/attributes.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ mod parse {
1111
actual,
1212
vec![
1313
("*.[oa]".into(), Mode::NO_SUB_DIR, 2),
14-
("*.html".into(), Mode::NO_SUB_DIR, 5),
14+
("*.html".into(), Mode::NO_SUB_DIR | Mode::ENDS_WITH, 5),
1515
("foo.html".into(), Mode::NO_SUB_DIR | Mode::NEGATIVE, 8),
1616
("/*".into(), Mode::empty(), 11),
1717
("/foo".into(), Mode::NEGATIVE, 12),
@@ -33,6 +33,32 @@ mod parse {
3333
);
3434
}
3535

36+
#[test]
37+
fn mark_ends_with_pattern_specifically() {
38+
assert_eq!(
39+
git_attributes::parse::ignore(br"*literal").next(),
40+
Some((r"*literal".into(), Mode::NO_SUB_DIR | Mode::ENDS_WITH, 1))
41+
);
42+
assert_eq!(
43+
git_attributes::parse::ignore(br"**literal").next(),
44+
Some((r"**literal".into(), Mode::NO_SUB_DIR, 1)),
45+
"double-asterisk won't allow for fast comparisons"
46+
);
47+
assert_eq!(
48+
git_attributes::parse::ignore(br"*litera[l]").next(),
49+
Some((r"*litera[l]".into(), Mode::NO_SUB_DIR, 1))
50+
);
51+
assert_eq!(
52+
git_attributes::parse::ignore(br"*litera?").next(),
53+
Some((r"*litera?".into(), Mode::NO_SUB_DIR, 1))
54+
);
55+
assert_eq!(
56+
git_attributes::parse::ignore(br"*litera\?").next(),
57+
Some((r"*litera\?".into(), Mode::NO_SUB_DIR, 1)),
58+
"for now we don't handle escapes properly like git seems to do"
59+
);
60+
}
61+
3662
#[test]
3763
fn comments_are_ignored() {
3864
assert!(git_attributes::parse::ignore(b"# hello world").next().is_none());

0 commit comments

Comments
 (0)