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
12 pub path: BString,12 pub path: BString,
13 /// All magig sigantures that were included in the pathspec.13 /// All magig sigantures that were included in the pathspec.
14 pub signature: Option<MagicSignature>,14 pub signature: Option<MagicSignature>,
15 // All attributes that were included in the `ATTR` part of the pathspec, if present.15 /// All attributes that were included in the `ATTR` part of the pathspec, if present.
16 // pub attributes: Vec<(BString, git_attributes::State)>,16 pub attributes: Vec<(BString, git_attributes::State)>,
17}17}
18 18
19bitflags! {19bitflags! {
git-pathspec/src/parse.rs+24−9
@@ -38,17 +38,24 @@ impl<'a> Parser<'a> { · 37 unmodified lines
38 }38 }
39 39
40 fn parse(mut self) -> Result<Pattern, Error> {40 fn parse(mut self) -> Result<Pattern, Error> {
41 let signature = self.parse_magic_signature()?;41 let (signature, attributes) = self.parse_magic_signature()?;
42 let path = self.parse_path();42 let path = self.parse_path();
43 43
44 Ok(Pattern { path, signature })44 Ok(Pattern {
45 path,
46 signature,
47 attributes,
48 })
45 }49 }
46 50
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> {
48 match self.input.peek() {54 match self.input.peek() {
49 Some(b':') => {55 Some(b':') => {
50 self.input.next();56 self.input.next();
51 let mut signature = MagicSignature::empty();57 let mut signature = MagicSignature::empty();
58 let mut attributes = Vec::new();
52 59
53 while let Some(&b) = self.input.peek() {60 while let Some(&b) = self.input.peek() {
54 match b {61 match b {
@@ -68,21 +75,28 @@ impl<'a> Parser<'a> { · 13 unmodified lines
68 }75 }
69 b'(' => {76 b'(' => {
70 self.input.next();77 self.input.next();
71 signature |= self.parse_magic_keywords()?;78 let (signatures, attrs) = self.parse_magic_keywords()?;
79 signature |= signatures;
80 attributes = attrs;
72 }81 }
73 _ => break,82 _ => break,
74 }83 }
75 }84 }
76 85
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))
78 }91 }
79 _ => Ok(None),92 _ => Ok((None, Vec::new())),
80 }93 }
81 }94 }
82 95
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> {
84 let mut buf = Vec::new();97 let mut buf = Vec::new();
85 let mut keywords = Vec::new();98 let mut keywords = Vec::new();
99 let mut attributes = Vec::new();
86 100
87 while let Some(b) = self.input.next() {101 while let Some(b) = self.input.next() {
88 match b {102 match b {
@@ -114,9 +128,10 @@ impl<'a> Parser<'a> { · 25 unmodified lines
114 b"attr" => MagicSignature::ATTR,128 b"attr" => MagicSignature::ATTR,
115 b"exclude" => MagicSignature::EXCLUDE,129 b"exclude" => MagicSignature::EXCLUDE,
116 s if s.starts_with(b"attr:") => git_attributes::parse::Iter::new(s[5..].into(), 0)130 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))))
117 .collect::<Result<Vec<_>, _>>()132 .collect::<Result<Vec<_>, _>>()
118 .map(|v| {133 .map(|v| {
119 println!("{:?}", v);134 attributes = v;
120 MagicSignature::ATTR135 MagicSignature::ATTR
121 })?,136 })?,
122 s => {137 s => {
@@ -127,7 +142,7 @@ impl<'a> Parser<'a> { · 4 unmodified lines
127 }142 }
128 }143 }
129 144
130 Ok(signature)145 Ok((signature, attributes))
131 }146 }
132 147
133 fn parse_path(self) -> BString {148 fn parse_path(self) -> BString {
git-pathspec/tests/pathspec.rs+59−23
@@ -1,25 +1,49 @@
1use bstr::BString;1use bstr::BString;
2use git_attributes::State;
2use git_pathspec::{MagicSignature, Pattern};3use git_pathspec::{MagicSignature, Pattern};
3 4
4#[test]5#[test]
5fn can_parse() {6fn can_parse() {
6 let inputs = vec![7 let inputs = vec![
7 ("some/path", pat("some/path", None)),8 ("some/path", pat("some/path", None, vec![])),
8 ("some/*.path", pat("some/*.path", None)),9 ("some/*.path", pat("some/*.path", None, vec![])),
9 (":/", pat("", Some(MagicSignature::TOP))),10 (":/", pat("", Some(MagicSignature::TOP), vec![])),
10 (":^", pat("", Some(MagicSignature::EXCLUDE))),11 (":^", pat("", Some(MagicSignature::EXCLUDE), vec![])),
11 (":!", pat("", Some(MagicSignature::EXCLUDE))),12 (":!", pat("", Some(MagicSignature::EXCLUDE), vec![])),
12 (":(top)", pat("", Some(MagicSignature::TOP))),13 (":(top)", pat("", Some(MagicSignature::TOP), vec![])),
13 (":(literal)", pat("", Some(MagicSignature::LITERAL))),14 (":(literal)", pat("", Some(MagicSignature::LITERAL), vec![])),
14 (":(icase)", pat("", Some(MagicSignature::ICASE))),15 (":(icase)", pat("", Some(MagicSignature::ICASE), vec![])),
15 (":(glob)", pat("", Some(MagicSignature::GLOB))),16 (":(glob)", pat("", Some(MagicSignature::GLOB), vec![])),
16 (":(attr)", pat("", Some(MagicSignature::ATTR))),17 (":(attr)", pat("", Some(MagicSignature::ATTR), vec![])),
17 (":(attr:someAttr)", pat("", Some(MagicSignature::ATTR))),18 (
18 (":(attr:!someAttr)", pat("", Some(MagicSignature::ATTR))),19 ":(attr:someAttr)",
19 (":(attr:-someAttr)", pat("", Some(MagicSignature::ATTR))),20 pat("", Some(MagicSignature::ATTR), vec![("someAttr", State::Set)]),
20 (":(attr:someAttr=value)", pat("", Some(MagicSignature::ATTR))),21 ),
21 (":(attr:someAttr anotherAttr)", pat("", Some(MagicSignature::ATTR))),22 (
22 (":(exclude)", pat("", Some(MagicSignature::EXCLUDE))),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![])),
23 // TODO:47 // TODO:
24 // 'literal' and 'glob' cannot appear in the same pathspec together48 // 'literal' and 'glob' cannot appear in the same pathspec together
25 // is this the parsers job to handle?49 // is this the parsers job to handle?
@@ -35,17 +59,25 @@ fn can_parse() { · 9 unmodified lines
35 // | MagicSignature::ATTR59 // | MagicSignature::ATTR
36 // | MagicSignature::EXCLUDE,60 // | MagicSignature::EXCLUDE,
37 // ),61 // ),
62 // vec![]
38 // ),63 // ),
39 // ),64 // ),
40 (":/:some/path", pat("some/path", Some(MagicSignature::TOP))),65 (":/:some/path", pat("some/path", Some(MagicSignature::TOP), vec![])),
41 (66 (
42 ":!(literal)some/*path",67 ":!(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![]),
44 ),80 ),
45 (":", pat("", None)),
46 (":()", pat("", None)),
47 (":::::", pat("", None)),
48 (":!/!/:", pat("", Some(MagicSignature::TOP | MagicSignature::EXCLUDE))),
49 ];81 ];
50 82
51 for (input, expected) in inputs {83 for (input, expected) in inputs {
@@ -98,10 +130,14 @@ fn should_fail_on_whitespace_or_invalid_keywords() { · 46 unmodified lines
98 }130 }
99}131}
100 132
101fn pat(path: &str, signature: Option<MagicSignature>) -> Pattern {133fn pat(path: &str, signature: Option<MagicSignature>, attributes: Vec<(&str, State)>) -> Pattern {
102 Pattern {134 Pattern {
103 path: path.into(),135 path: path.into(),
104 signature,136 signature,
137 attributes: attributes
138 .into_iter()
139 .map(|(attr, state)| (attr.into(), state))
140 .collect(),
105 }141 }
106}142}
107 143

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