History

attribute parsing functional (#415)

Sidney Douw committed 4 years ago

Commit 4b2ed7e1 parent 8b9570f3 files · +85 −34Browse files

Unified · Split

3 files
  1. git-pathspec/src/lib.rs +2 −2
  2. git-pathspec/src/parse.rs +24 −9
  3. git-pathspec/tests/pathspec.rs +59 −23
git-pathspec/src/lib.rs+2−2
@@ -12,8 +12,8 @@ pub struct Pattern { · 11 unmodified lines
1212 pub path: BString,
1313 /// All magig sigantures that were included in the pathspec.
1414 pub signature: Option<MagicSignature>,
15− // All attributes that were included in the `ATTR` part of the pathspec, if present.
16− // pub attributes: Vec<(BString, git_attributes::State)>,
15+ /// All attributes that were included in the `ATTR` part of the pathspec, if present.
16+ pub attributes: Vec<(BString, git_attributes::State)>,
1717 }
1818
1919 bitflags! {
git-pathspec/src/parse.rs+24−9
@@ -38,17 +38,24 @@ impl<'a> Parser<'a> { · 37 unmodified lines
3838 }
3939
4040 fn parse(mut self) -> Result<Pattern, Error> {
41− let signature = self.parse_magic_signature()?;
41+ let (signature, attributes) = self.parse_magic_signature()?;
4242 let path = self.parse_path();
4343
44− Ok(Pattern { path, signature })
44+ Ok(Pattern {
45+ path,
46+ signature,
47+ attributes,
48+ })
4549 }
4650
47− fn parse_magic_signature(&mut self) -> Result<Option<MagicSignature>, Error> {
51+ fn parse_magic_signature(
52+ &mut self,
53+ ) -> Result<(Option<MagicSignature>, Vec<(BString, git_attributes::State)>), Error> {
4854 match self.input.peek() {
4955 Some(b':') => {
5056 self.input.next();
5157 let mut signature = MagicSignature::empty();
58+ let mut attributes = Vec::new();
5259
5360 while let Some(&b) = self.input.peek() {
5461 match b {
@@ -68,21 +75,28 @@ impl<'a> Parser<'a> { · 13 unmodified lines
6875 }
6976 b'(' => {
7077 self.input.next();
71− signature |= self.parse_magic_keywords()?;
78+ let (signatures, attrs) = self.parse_magic_keywords()?;
79+ signature |= signatures;
80+ attributes = attrs;
7281 }
7382 _ => break,
7483 }
7584 }
7685
77− (!signature.is_empty()).then(|| signature).map(Result::Ok).transpose()
86+ (!signature.is_empty())
87+ .then(|| signature)
88+ .map(Result::Ok)
89+ .transpose()
90+ .map(|x| (x, attributes))
7891 }
79− _ => Ok(None),
92+ _ => Ok((None, Vec::new())),
8093 }
8194 }
8295
83− fn parse_magic_keywords(&mut self) -> Result<MagicSignature, Error> {
96+ fn parse_magic_keywords(&mut self) -> Result<(MagicSignature, Vec<(BString, git_attributes::State)>), Error> {
8497 let mut buf = Vec::new();
8598 let mut keywords = Vec::new();
99+ let mut attributes = Vec::new();
86100
87101 while let Some(b) = self.input.next() {
88102 match b {
@@ -114,9 +128,10 @@ impl<'a> Parser<'a> { · 25 unmodified lines
114128 b"attr" => MagicSignature::ATTR,
115129 b"exclude" => MagicSignature::EXCLUDE,
116130 s if s.starts_with(b"attr:") => git_attributes::parse::Iter::new(s[5..].into(), 0)
131+ .map(|res| res.map(|(attr, state)| (BString::from(attr), git_attributes::State::from(state))))
117132 .collect::<Result<Vec<_>, _>>()
118133 .map(|v| {
119− println!("{:?}", v);
134+ attributes = v;
120135 MagicSignature::ATTR
121136 })?,
122137 s => {
@@ -127,7 +142,7 @@ impl<'a> Parser<'a> { · 4 unmodified lines
127142 }
128143 }
129144
130− Ok(signature)
145+ Ok((signature, attributes))
131146 }
132147
133148 fn parse_path(self) -> BString {
git-pathspec/tests/pathspec.rs+59−23
@@ -1,25 +1,49 @@
11 use bstr::BString;
2+use git_attributes::State;
23 use git_pathspec::{MagicSignature, Pattern};
34
45 #[test]
56 fn can_parse() {
67 let inputs = vec![
7− ("some/path", pat("some/path", None)),
8− ("some/*.path", pat("some/*.path", None)),
9− (":/", pat("", Some(MagicSignature::TOP))),
10− (":^", pat("", Some(MagicSignature::EXCLUDE))),
11− (":!", pat("", Some(MagicSignature::EXCLUDE))),
12− (":(top)", pat("", Some(MagicSignature::TOP))),
13− (":(literal)", pat("", Some(MagicSignature::LITERAL))),
14− (":(icase)", pat("", Some(MagicSignature::ICASE))),
15− (":(glob)", pat("", Some(MagicSignature::GLOB))),
16− (":(attr)", pat("", Some(MagicSignature::ATTR))),
17− (":(attr:someAttr)", pat("", Some(MagicSignature::ATTR))),
18− (":(attr:!someAttr)", pat("", Some(MagicSignature::ATTR))),
19− (":(attr:-someAttr)", pat("", Some(MagicSignature::ATTR))),
20− (":(attr:someAttr=value)", pat("", Some(MagicSignature::ATTR))),
21− (":(attr:someAttr anotherAttr)", pat("", Some(MagicSignature::ATTR))),
22− (":(exclude)", pat("", Some(MagicSignature::EXCLUDE))),
8+ ("some/path", pat("some/path", None, vec![])),
9+ ("some/*.path", pat("some/*.path", None, vec![])),
10+ (":/", pat("", Some(MagicSignature::TOP), vec![])),
11+ (":^", pat("", Some(MagicSignature::EXCLUDE), vec![])),
12+ (":!", pat("", Some(MagicSignature::EXCLUDE), vec![])),
13+ (":(top)", pat("", Some(MagicSignature::TOP), vec![])),
14+ (":(literal)", pat("", Some(MagicSignature::LITERAL), vec![])),
15+ (":(icase)", pat("", Some(MagicSignature::ICASE), vec![])),
16+ (":(glob)", pat("", Some(MagicSignature::GLOB), vec![])),
17+ (":(attr)", pat("", Some(MagicSignature::ATTR), vec![])),
18+ (
19+ ":(attr:someAttr)",
20+ pat("", Some(MagicSignature::ATTR), vec![("someAttr", State::Set)]),
21+ ),
22+ (
23+ ":(attr:!someAttr)",
24+ pat("", Some(MagicSignature::ATTR), vec![("someAttr", State::Unspecified)]),
25+ ),
26+ (
27+ ":(attr:-someAttr)",
28+ pat("", Some(MagicSignature::ATTR), vec![("someAttr", State::Unset)]),
29+ ),
30+ (
31+ ":(attr:someAttr=value)",
32+ pat(
33+ "",
34+ Some(MagicSignature::ATTR),
35+ vec![("someAttr", State::Value("value".into()))],
36+ ),
37+ ),
38+ (
39+ ":(attr:someAttr anotherAttr)",
40+ pat(
41+ "",
42+ Some(MagicSignature::ATTR),
43+ vec![("someAttr", State::Set), ("anotherAttr", State::Set)],
44+ ),
45+ ),
46+ (":(exclude)", pat("", Some(MagicSignature::EXCLUDE), vec![])),
2347 // TODO:
2448 // 'literal' and 'glob' cannot appear in the same pathspec together
2549 // is this the parsers job to handle?
@@ -35,17 +59,25 @@ fn can_parse() { · 9 unmodified lines
3559 // | MagicSignature::ATTR
3660 // | MagicSignature::EXCLUDE,
3761 // ),
62+ // vec![]
3863 // ),
3964 // ),
40− (":/:some/path", pat("some/path", Some(MagicSignature::TOP))),
65+ (":/:some/path", pat("some/path", Some(MagicSignature::TOP), vec![])),
4166 (
4267 ":!(literal)some/*path",
43− pat("some/*path", Some(MagicSignature::EXCLUDE | MagicSignature::LITERAL)),
68+ pat(
69+ "some/*path",
70+ Some(MagicSignature::EXCLUDE | MagicSignature::LITERAL),
71+ vec![],
72+ ),
73+ ),
74+ (":", pat("", None, vec![])),
75+ (":()", pat("", None, vec![])),
76+ (":::::", pat("", None, vec![])),
77+ (
78+ ":!/!/:",
79+ pat("", Some(MagicSignature::TOP | MagicSignature::EXCLUDE), vec![]),
4480 ),
45− (":", pat("", None)),
46− (":()", pat("", None)),
47− (":::::", pat("", None)),
48− (":!/!/:", pat("", Some(MagicSignature::TOP | MagicSignature::EXCLUDE))),
4981 ];
5082
5183 for (input, expected) in inputs {
@@ -98,10 +130,14 @@ fn should_fail_on_whitespace_or_invalid_keywords() { · 46 unmodified lines
98130 }
99131 }
100132
101−fn pat(path: &str, signature: Option<MagicSignature>) -> Pattern {
133+fn pat(path: &str, signature: Option<MagicSignature>, attributes: Vec<(&str, State)>) -> Pattern {
102134 Pattern {
103135 path: path.into(),
104136 signature,
137+ attributes: attributes
138+ .into_iter()
139+ .map(|(attr, state)| (attr.into(), state))
140+ .collect(),
105141 }
106142 }
107143

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t