@@ -27,14 +27,18 @@ pub fn new() -> Compiler {
27
27
}
28
28
29
29
/// Creates a new boon::compiler with format assertions enabled and validation
30
- /// for the custom `path` and `license` formats.
30
+ /// for the custom `path`, `glob`, and `license` formats.
31
31
pub fn spec_compiler ( ) -> Compiler {
32
32
let mut compiler = Compiler :: new ( ) ;
33
33
compiler. enable_format_assertions ( ) ;
34
34
compiler. register_format ( boon:: Format {
35
35
name : "path" ,
36
36
func : is_path,
37
37
} ) ;
38
+ compiler. register_format ( boon:: Format {
39
+ name : "glob" ,
40
+ func : is_glob,
41
+ } ) ;
38
42
compiler. register_format ( boon:: Format {
39
43
name : "license" ,
40
44
func : is_license,
@@ -46,11 +50,25 @@ pub fn spec_compiler() -> Compiler {
46
50
fn is_path ( v : & Value ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
47
51
let Value :: String ( s) = v else { return Ok ( ( ) ) } ;
48
52
49
- let path = RelativePath :: new ( s) ;
53
+ let path = RelativePath :: new ( s. strip_prefix ( "./" ) . unwrap_or ( s ) ) ;
50
54
for c in path. components ( ) {
51
- if c == Component :: ParentDir {
52
- Err ( "references parent dir" ) ?
53
- } ;
55
+ match c {
56
+ Component :: ParentDir => Err ( "references parent directory" ) ?,
57
+ Component :: CurDir => Err ( "references current directory" ) ?,
58
+ _ => ( ) ,
59
+ }
60
+ }
61
+
62
+ Ok ( ( ) )
63
+ }
64
+
65
+ /// Returns an error if v is not a valid glob.
66
+ fn is_glob ( v : & Value ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
67
+ let Value :: String ( s) = v else { return Ok ( ( ) ) } ;
68
+
69
+ let path = wax:: Glob :: new ( s. strip_prefix ( "./" ) . unwrap_or ( s) ) ?;
70
+ if path. has_semantic_literals ( ) {
71
+ Err ( "references parent or current directory" ) ?
54
72
}
55
73
56
74
Ok ( ( ) )
@@ -77,6 +95,7 @@ mod tests {
77
95
json ! ( "\\ foo.md" ) ,
78
96
json ! ( "this\\ and\\ that.txt" ) ,
79
97
json ! ( "/absolute/path" ) ,
98
+ json ! ( "./relative/path" ) ,
80
99
json ! ( "" ) ,
81
100
json ! ( "C:\\ foo" ) ,
82
101
json ! ( "README.txt" ) ,
@@ -92,11 +111,20 @@ mod tests {
92
111
93
112
// Test invalid paths.
94
113
for ( name, invalid, err) in [
95
- ( "parent" , json ! ( "../outside/path" ) , "references parent dir" ) ,
114
+ (
115
+ "parent" ,
116
+ json ! ( "../outside/path" ) ,
117
+ "references parent directory" ,
118
+ ) ,
119
+ (
120
+ "current" ,
121
+ json ! ( "/./outside/path" ) ,
122
+ "references current directory" ,
123
+ ) ,
96
124
(
97
125
"sub parent" ,
98
126
json ! ( "thing/../other" ) ,
99
- "references parent dir " ,
127
+ "references parent directory " ,
100
128
) ,
101
129
] {
102
130
match is_path ( & invalid) {
@@ -106,6 +134,42 @@ mod tests {
106
134
}
107
135
}
108
136
137
+ #[ test]
138
+ fn test_glob ( ) {
139
+ // Test valid globs.
140
+ for valid in [
141
+ json ! ( ".gitignore" ) ,
142
+ json ! ( ".git*" ) ,
143
+ json ! ( "/git*" ) ,
144
+ json ! ( "./git*" ) ,
145
+ json ! ( "" ) ,
146
+ json ! ( "README.*" ) ,
147
+ json ! ( "**/*.(?i){jpg,jpeg}" ) ,
148
+ json ! ( "**/{*.{go,rs}}" ) ,
149
+ json ! ( "src/**/*.rs" ) ,
150
+ ] {
151
+ if let Err ( e) = is_glob ( & valid) {
152
+ panic ! ( "{} failed: {e}" , valid) ;
153
+ }
154
+ }
155
+
156
+ // Test invalid paths.
157
+ for ( name, invalid) in [
158
+ ( "parent" , json ! ( "../*.c" ) ) ,
159
+ ( "current" , json ! ( "/./*.c" ) ) ,
160
+ ( "sub parent" , json ! ( "/**/../passwd" ) ) ,
161
+ ] {
162
+ match is_glob ( & invalid) {
163
+ Ok ( _) => panic ! ( "{name} unexpectedly passed!" ) ,
164
+ Err ( e) => assert_eq ! (
165
+ "references parent or current directory" ,
166
+ e. to_string( ) ,
167
+ "{name}"
168
+ ) ,
169
+ }
170
+ }
171
+ }
172
+
109
173
#[ test]
110
174
fn test_license ( ) {
111
175
// Test valid relative licenses.
@@ -163,7 +227,7 @@ mod tests {
163
227
fn test_spec_compiler ( ) -> Result < ( ) , Error > {
164
228
let mut c = spec_compiler ( ) ;
165
229
let id = "format" ;
166
- // Compile simple schema to validate license and path .
230
+ // Compile simple schema to validate license, path, and glob .
167
231
c. add_resource (
168
232
id,
169
233
json ! ( {
@@ -173,6 +237,10 @@ mod tests {
173
237
"type" : "string" ,
174
238
"format" : "path" ,
175
239
} ,
240
+ "glob" : {
241
+ "type" : "string" ,
242
+ "format" : "glob" ,
243
+ } ,
176
244
"license" : {
177
245
"type" : "string" ,
178
246
"format" : "license" ,
@@ -198,7 +266,12 @@ mod tests {
198
266
(
199
267
"parent path" ,
200
268
json ! ( { "path" : "../foo" } ) ,
201
- "'../foo' is not valid path: references parent dir" ,
269
+ "'../foo' is not valid path: references parent directory" ,
270
+ ) ,
271
+ (
272
+ "parent glob" ,
273
+ json ! ( { "glob" : "../*.c" } ) ,
274
+ "'../*.c' is not valid glob: references parent or current directory" ,
202
275
) ,
203
276
] {
204
277
match schemas. validate ( & json, idx) {
0 commit comments