Skip to content

Commit 6131173

Browse files
committed
Merge pull request #25 from blaenk/relative-paths
if input relative patterns, output relative paths
2 parents 42ddf87 + 610d493 commit 6131173

File tree

2 files changed

+139
-125
lines changed

2 files changed

+139
-125
lines changed

src/lib.rs

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
use std::ascii::AsciiExt;
2929
use std::cell::Cell;
30-
use std::{cmp, os, path};
30+
use std::{cmp, path};
3131
use std::io::fs::{self, PathExtensions};
3232
use std::path::is_sep;
3333
use std::string::String;
@@ -91,36 +91,50 @@ pub fn glob_with(pattern: &str, options: &MatchOptions) -> Paths {
9191
#[cfg(not(windows))]
9292
fn check_windows_verbatim(_: &Path) -> bool { false }
9393

94-
// calculate root this way to handle volume-relative Windows paths correctly
95-
let mut root = os::getcwd().unwrap();
96-
let pat_root = Path::new(pattern).root_path();
97-
if pat_root.is_some() {
98-
if check_windows_verbatim(pat_root.as_ref().unwrap()) {
99-
// FIXME: How do we want to handle verbatim paths? I'm inclined to return nothing,
100-
// since we can't very well find all UNC shares with a 1-letter server name.
101-
return Paths {
102-
dir_patterns: Vec::new(),
103-
require_dir: false,
104-
options: options.clone(),
105-
todo: Vec::new(),
106-
};
94+
#[cfg(windows)]
95+
fn to_scope(p: Path) -> Path {
96+
use std::os::getcwd;
97+
98+
if path::windows::is_vol_relative(&p) {
99+
let mut cwd = getcwd().unwrap();
100+
cwd.push(p);
101+
cwd
102+
} else {
103+
p
107104
}
108-
root.push(pat_root.as_ref().unwrap());
105+
}
106+
#[cfg(not(windows))]
107+
fn to_scope(p: Path) -> Path { p }
108+
109+
let root = Path::new(pattern).root_path();
110+
let root_len = root.as_ref().map_or(0us, |p| p.as_vec().len());
111+
112+
if root.is_some() && check_windows_verbatim(root.as_ref().unwrap()) {
113+
// FIXME: How do we want to handle verbatim paths? I'm inclined to return nothing,
114+
// since we can't very well find all UNC shares with a 1-letter server name.
115+
return Paths {
116+
dir_patterns: Vec::new(),
117+
require_dir: false,
118+
options: options.clone(),
119+
todo: Vec::new(),
120+
};
109121
}
110122

111-
let root_len = pat_root.map_or(0us, |p| p.as_vec().len());
123+
let scope = root.map(to_scope).unwrap_or_else(|| Path::new("."));
124+
112125
let dir_patterns = pattern.slice_from(cmp::min(root_len, pattern.len()))
113126
.split_terminator(is_sep)
114127
.map(|s| Pattern::new(s))
115128
.collect::<Vec<Pattern>>();
129+
116130
let require_dir = pattern.chars().next_back().map(is_sep) == Some(true);
117131

118132
let mut todo = Vec::new();
119133
if dir_patterns.len() > 0 {
120134
// Shouldn't happen, but we're using -1 as a special index.
121135
assert!(dir_patterns.len() < -1 as usize);
122136

123-
fill_todo(&mut todo, dir_patterns.as_slice(), 0, &root, options);
137+
fill_todo(&mut todo, dir_patterns.as_slice(), 0, &scope, options);
124138
}
125139

126140
Paths {

tests/glob-std.rs

Lines changed: 108 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -86,193 +86,193 @@ fn main() {
8686

8787
// all recursive entities
8888
assert_eq!(glob_vec("r/**"), vec!(
89-
abs_path("r/another"),
90-
abs_path("r/another/a.md"),
91-
abs_path("r/current_dir.md"),
92-
abs_path("r/one"),
93-
abs_path("r/one/a.md"),
94-
abs_path("r/one/another"),
95-
abs_path("r/one/another/a.md"),
96-
abs_path("r/three"),
97-
abs_path("r/three/c.md"),
98-
abs_path("r/two"),
99-
abs_path("r/two/b.md")));
89+
Path::new("r/another"),
90+
Path::new("r/another/a.md"),
91+
Path::new("r/current_dir.md"),
92+
Path::new("r/one"),
93+
Path::new("r/one/a.md"),
94+
Path::new("r/one/another"),
95+
Path::new("r/one/another/a.md"),
96+
Path::new("r/three"),
97+
Path::new("r/three/c.md"),
98+
Path::new("r/two"),
99+
Path::new("r/two/b.md")));
100100

101101
// collapse consecutive recursive patterns
102102
assert_eq!(glob_vec("r/**/**"), vec!(
103-
abs_path("r/another"),
104-
abs_path("r/another/a.md"),
105-
abs_path("r/current_dir.md"),
106-
abs_path("r/one"),
107-
abs_path("r/one/a.md"),
108-
abs_path("r/one/another"),
109-
abs_path("r/one/another/a.md"),
110-
abs_path("r/three"),
111-
abs_path("r/three/c.md"),
112-
abs_path("r/two"),
113-
abs_path("r/two/b.md")));
103+
Path::new("r/another"),
104+
Path::new("r/another/a.md"),
105+
Path::new("r/current_dir.md"),
106+
Path::new("r/one"),
107+
Path::new("r/one/a.md"),
108+
Path::new("r/one/another"),
109+
Path::new("r/one/another/a.md"),
110+
Path::new("r/three"),
111+
Path::new("r/three/c.md"),
112+
Path::new("r/two"),
113+
Path::new("r/two/b.md")));
114114

115115
// followed by a wildcard
116116
assert_eq!(glob_vec("r/**/*.md"), vec!(
117-
abs_path("r/another/a.md"),
118-
abs_path("r/current_dir.md"),
119-
abs_path("r/one/a.md"),
120-
abs_path("r/one/another/a.md"),
121-
abs_path("r/three/c.md"),
122-
abs_path("r/two/b.md")));
117+
Path::new("r/another/a.md"),
118+
Path::new("r/current_dir.md"),
119+
Path::new("r/one/a.md"),
120+
Path::new("r/one/another/a.md"),
121+
Path::new("r/three/c.md"),
122+
Path::new("r/two/b.md")));
123123

124124
// followed by a precise pattern
125125
assert_eq!(glob_vec("r/one/**/a.md"), vec!(
126-
abs_path("r/one/a.md"),
127-
abs_path("r/one/another/a.md")));
126+
Path::new("r/one/a.md"),
127+
Path::new("r/one/another/a.md")));
128128

129129
// followed by another recursive pattern
130130
// collapses consecutive recursives into one
131131
assert_eq!(glob_vec("r/one/**/**/a.md"), vec!(
132-
abs_path("r/one/a.md"),
133-
abs_path("r/one/another/a.md")));
132+
Path::new("r/one/a.md"),
133+
Path::new("r/one/another/a.md")));
134134

135135
// followed by two precise patterns
136136
assert_eq!(glob_vec("r/**/another/a.md"), vec!(
137-
abs_path("r/another/a.md"),
138-
abs_path("r/one/another/a.md")));
137+
Path::new("r/another/a.md"),
138+
Path::new("r/one/another/a.md")));
139139

140140
assert_eq!(glob_vec(""), Vec::new());
141-
assert_eq!(glob_vec("."), vec!(os::getcwd().unwrap()));
142-
assert_eq!(glob_vec(".."), vec!(os::getcwd().unwrap().join("..")));
141+
assert_eq!(glob_vec("."), vec!(Path::new(".")));
142+
assert_eq!(glob_vec(".."), vec!(Path::new("..")));
143143

144-
assert_eq!(glob_vec("aaa"), vec!(abs_path("aaa")));
145-
assert_eq!(glob_vec("aaa/"), vec!(abs_path("aaa")));
144+
assert_eq!(glob_vec("aaa"), vec!(Path::new("aaa")));
145+
assert_eq!(glob_vec("aaa/"), vec!(Path::new("aaa")));
146146
assert_eq!(glob_vec("a"), Vec::new());
147147
assert_eq!(glob_vec("aa"), Vec::new());
148148
assert_eq!(glob_vec("aaaa"), Vec::new());
149149

150-
assert_eq!(glob_vec("aaa/apple"), vec!(abs_path("aaa/apple")));
150+
assert_eq!(glob_vec("aaa/apple"), vec!(Path::new("aaa/apple")));
151151
assert_eq!(glob_vec("aaa/apple/nope"), Vec::new());
152152

153153
// windows should support both / and \ as directory separators
154154
if os::consts::FAMILY == "windows" {
155-
assert_eq!(glob_vec("aaa\\apple"), vec!(abs_path("aaa/apple")));
155+
assert_eq!(glob_vec("aaa\\apple"), vec!(Path::new("aaa/apple")));
156156
}
157157

158158
assert_eq!(glob_vec("???/"), vec!(
159-
abs_path("aaa"),
160-
abs_path("bbb"),
161-
abs_path("ccc"),
162-
abs_path("xyz")));
159+
Path::new("aaa"),
160+
Path::new("bbb"),
161+
Path::new("ccc"),
162+
Path::new("xyz")));
163163

164164
assert_eq!(glob_vec("aaa/tomato/tom?to.txt"), vec!(
165-
abs_path("aaa/tomato/tomato.txt"),
166-
abs_path("aaa/tomato/tomoto.txt")));
165+
Path::new("aaa/tomato/tomato.txt"),
166+
Path::new("aaa/tomato/tomoto.txt")));
167167

168168
assert_eq!(glob_vec("xyz/?"), vec!(
169-
abs_path("xyz/x"),
170-
abs_path("xyz/y"),
171-
abs_path("xyz/z")));
172-
173-
assert_eq!(glob_vec("a*"), vec!(abs_path("aaa")));
174-
assert_eq!(glob_vec("*a*"), vec!(abs_path("aaa")));
175-
assert_eq!(glob_vec("a*a"), vec!(abs_path("aaa")));
176-
assert_eq!(glob_vec("aaa*"), vec!(abs_path("aaa")));
177-
assert_eq!(glob_vec("*aaa"), vec!(abs_path("aaa")));
178-
assert_eq!(glob_vec("*aaa*"), vec!(abs_path("aaa")));
179-
assert_eq!(glob_vec("*a*a*a*"), vec!(abs_path("aaa")));
180-
assert_eq!(glob_vec("aaa*/"), vec!(abs_path("aaa")));
169+
Path::new("xyz/x"),
170+
Path::new("xyz/y"),
171+
Path::new("xyz/z")));
172+
173+
assert_eq!(glob_vec("a*"), vec!(Path::new("aaa")));
174+
assert_eq!(glob_vec("*a*"), vec!(Path::new("aaa")));
175+
assert_eq!(glob_vec("a*a"), vec!(Path::new("aaa")));
176+
assert_eq!(glob_vec("aaa*"), vec!(Path::new("aaa")));
177+
assert_eq!(glob_vec("*aaa"), vec!(Path::new("aaa")));
178+
assert_eq!(glob_vec("*aaa*"), vec!(Path::new("aaa")));
179+
assert_eq!(glob_vec("*a*a*a*"), vec!(Path::new("aaa")));
180+
assert_eq!(glob_vec("aaa*/"), vec!(Path::new("aaa")));
181181

182182
assert_eq!(glob_vec("aaa/*"), vec!(
183-
abs_path("aaa/apple"),
184-
abs_path("aaa/orange"),
185-
abs_path("aaa/tomato")));
183+
Path::new("aaa/apple"),
184+
Path::new("aaa/orange"),
185+
Path::new("aaa/tomato")));
186186

187187
assert_eq!(glob_vec("aaa/*a*"), vec!(
188-
abs_path("aaa/apple"),
189-
abs_path("aaa/orange"),
190-
abs_path("aaa/tomato")));
188+
Path::new("aaa/apple"),
189+
Path::new("aaa/orange"),
190+
Path::new("aaa/tomato")));
191191

192192
assert_eq!(glob_vec("*/*/*.txt"), vec!(
193-
abs_path("aaa/tomato/tomato.txt"),
194-
abs_path("aaa/tomato/tomoto.txt")));
193+
Path::new("aaa/tomato/tomato.txt"),
194+
Path::new("aaa/tomato/tomoto.txt")));
195195

196196
assert_eq!(glob_vec("*/*/t[aob]m?to[.]t[!y]t"), vec!(
197-
abs_path("aaa/tomato/tomato.txt"),
198-
abs_path("aaa/tomato/tomoto.txt")));
197+
Path::new("aaa/tomato/tomato.txt"),
198+
Path::new("aaa/tomato/tomoto.txt")));
199199

200-
assert_eq!(glob_vec("./aaa"), vec!(abs_path("aaa")));
200+
assert_eq!(glob_vec("./aaa"), vec!(Path::new("aaa")));
201201
assert_eq!(glob_vec("./*"), glob_vec("*"));
202-
assert_eq!(glob_vec("*/..").pop().unwrap(), abs_path("."));
203-
assert_eq!(glob_vec("aaa/../bbb"), vec!(abs_path("bbb")));
202+
assert_eq!(glob_vec("*/..").pop().unwrap(), Path::new("."));
203+
assert_eq!(glob_vec("aaa/../bbb"), vec!(Path::new("bbb")));
204204
assert_eq!(glob_vec("nonexistent/../bbb"), Vec::new());
205205
assert_eq!(glob_vec("aaa/tomato/tomato.txt/.."), Vec::new());
206206

207207
assert_eq!(glob_vec("aaa/tomato/tomato.txt/"), Vec::new());
208208

209-
assert_eq!(glob_vec("aa[a]"), vec!(abs_path("aaa")));
210-
assert_eq!(glob_vec("aa[abc]"), vec!(abs_path("aaa")));
211-
assert_eq!(glob_vec("a[bca]a"), vec!(abs_path("aaa")));
209+
assert_eq!(glob_vec("aa[a]"), vec!(Path::new("aaa")));
210+
assert_eq!(glob_vec("aa[abc]"), vec!(Path::new("aaa")));
211+
assert_eq!(glob_vec("a[bca]a"), vec!(Path::new("aaa")));
212212
assert_eq!(glob_vec("aa[b]"), Vec::new());
213213
assert_eq!(glob_vec("aa[xyz]"), Vec::new());
214214
assert_eq!(glob_vec("aa[]]"), Vec::new());
215215

216-
assert_eq!(glob_vec("aa[!b]"), vec!(abs_path("aaa")));
217-
assert_eq!(glob_vec("aa[!bcd]"), vec!(abs_path("aaa")));
218-
assert_eq!(glob_vec("a[!bcd]a"), vec!(abs_path("aaa")));
216+
assert_eq!(glob_vec("aa[!b]"), vec!(Path::new("aaa")));
217+
assert_eq!(glob_vec("aa[!bcd]"), vec!(Path::new("aaa")));
218+
assert_eq!(glob_vec("a[!bcd]a"), vec!(Path::new("aaa")));
219219
assert_eq!(glob_vec("aa[!a]"), Vec::new());
220220
assert_eq!(glob_vec("aa[!abc]"), Vec::new());
221221

222-
assert_eq!(glob_vec("bbb/specials/[[]"), vec!(abs_path("bbb/specials/[")));
223-
assert_eq!(glob_vec("bbb/specials/!"), vec!(abs_path("bbb/specials/!")));
224-
assert_eq!(glob_vec("bbb/specials/[]]"), vec!(abs_path("bbb/specials/]")));
222+
assert_eq!(glob_vec("bbb/specials/[[]"), vec!(Path::new("bbb/specials/[")));
223+
assert_eq!(glob_vec("bbb/specials/!"), vec!(Path::new("bbb/specials/!")));
224+
assert_eq!(glob_vec("bbb/specials/[]]"), vec!(Path::new("bbb/specials/]")));
225225

226226
if os::consts::FAMILY != "windows" {
227-
assert_eq!(glob_vec("bbb/specials/[*]"), vec!(abs_path("bbb/specials/*")));
228-
assert_eq!(glob_vec("bbb/specials/[?]"), vec!(abs_path("bbb/specials/?")));
227+
assert_eq!(glob_vec("bbb/specials/[*]"), vec!(Path::new("bbb/specials/*")));
228+
assert_eq!(glob_vec("bbb/specials/[?]"), vec!(Path::new("bbb/specials/?")));
229229
}
230230

231231
if os::consts::FAMILY == "windows" {
232232

233233
assert_eq!(glob_vec("bbb/specials/[![]"), vec!(
234-
abs_path("bbb/specials/!"),
235-
abs_path("bbb/specials/]")));
234+
Path::new("bbb/specials/!"),
235+
Path::new("bbb/specials/]")));
236236

237237
assert_eq!(glob_vec("bbb/specials/[!]]"), vec!(
238-
abs_path("bbb/specials/!"),
239-
abs_path("bbb/specials/[")));
238+
Path::new("bbb/specials/!"),
239+
Path::new("bbb/specials/[")));
240240

241241
assert_eq!(glob_vec("bbb/specials/[!!]"), vec!(
242-
abs_path("bbb/specials/["),
243-
abs_path("bbb/specials/]")));
242+
Path::new("bbb/specials/["),
243+
Path::new("bbb/specials/]")));
244244

245245
} else {
246246

247247
assert_eq!(glob_vec("bbb/specials/[![]"), vec!(
248-
abs_path("bbb/specials/!"),
249-
abs_path("bbb/specials/*"),
250-
abs_path("bbb/specials/?"),
251-
abs_path("bbb/specials/]")));
248+
Path::new("bbb/specials/!"),
249+
Path::new("bbb/specials/*"),
250+
Path::new("bbb/specials/?"),
251+
Path::new("bbb/specials/]")));
252252

253253
assert_eq!(glob_vec("bbb/specials/[!]]"), vec!(
254-
abs_path("bbb/specials/!"),
255-
abs_path("bbb/specials/*"),
256-
abs_path("bbb/specials/?"),
257-
abs_path("bbb/specials/[")));
254+
Path::new("bbb/specials/!"),
255+
Path::new("bbb/specials/*"),
256+
Path::new("bbb/specials/?"),
257+
Path::new("bbb/specials/[")));
258258

259259
assert_eq!(glob_vec("bbb/specials/[!!]"), vec!(
260-
abs_path("bbb/specials/*"),
261-
abs_path("bbb/specials/?"),
262-
abs_path("bbb/specials/["),
263-
abs_path("bbb/specials/]")));
260+
Path::new("bbb/specials/*"),
261+
Path::new("bbb/specials/?"),
262+
Path::new("bbb/specials/["),
263+
Path::new("bbb/specials/]")));
264264

265265
assert_eq!(glob_vec("bbb/specials/[!*]"), vec!(
266-
abs_path("bbb/specials/!"),
267-
abs_path("bbb/specials/?"),
268-
abs_path("bbb/specials/["),
269-
abs_path("bbb/specials/]")));
266+
Path::new("bbb/specials/!"),
267+
Path::new("bbb/specials/?"),
268+
Path::new("bbb/specials/["),
269+
Path::new("bbb/specials/]")));
270270

271271
assert_eq!(glob_vec("bbb/specials/[!?]"), vec!(
272-
abs_path("bbb/specials/!"),
273-
abs_path("bbb/specials/*"),
274-
abs_path("bbb/specials/["),
275-
abs_path("bbb/specials/]")));
272+
Path::new("bbb/specials/!"),
273+
Path::new("bbb/specials/*"),
274+
Path::new("bbb/specials/["),
275+
Path::new("bbb/specials/]")));
276276

277277
}
278278
}

0 commit comments

Comments
 (0)