OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /// A comprehensive, cross-platform path manipulation library. | 5 /// A comprehensive, cross-platform path manipulation library. |
6 library path; | 6 library path; |
7 | 7 |
8 import 'dart:io' as io; | 8 import 'dart:io' as io; |
9 | 9 |
10 /// An internal builder for the current OS so we can provide a straight | 10 /// An internal builder for the current OS so we can provide a straight |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
156 /// | 156 /// |
157 /// path.relative(r'D:\other', from: r'C:\home'); // -> 'D:\other' | 157 /// path.relative(r'D:\other', from: r'C:\home'); // -> 'D:\other' |
158 String relative(String path, {String from}) => | 158 String relative(String path, {String from}) => |
159 _builder.relative(path, from: from); | 159 _builder.relative(path, from: from); |
160 | 160 |
161 /// Removes a trailing extension from the last part of [path]. | 161 /// Removes a trailing extension from the last part of [path]. |
162 /// | 162 /// |
163 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' | 163 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' |
164 String withoutExtension(String path) => _builder.withoutExtension(path); | 164 String withoutExtension(String path) => _builder.withoutExtension(path); |
165 | 165 |
166 /// Validates that there are no non-null arguments following a null one and | |
167 /// throws an appropriate [ArgumentError] on failure. | |
168 _validateArgList(String method, List<String> args) { | |
169 for (var i = 1; i < args.length; i++) { | |
170 if (args[i] != null && args[i - 1] == null) { | |
nweiz
2013/01/19 00:35:47
Short-circuit?
Bob Nystrom
2013/01/22 23:53:19
Done.
| |
171 // Ignore nulls hanging off the end. | |
172 var numArgs; | |
173 for (numArgs = args.length; numArgs >= 1; numArgs--) { | |
174 if (args[numArgs - 1] != null) break; | |
175 } | |
176 | |
177 // Show the arguments. | |
178 var message = new StringBuffer(); | |
179 message.add("$method("); | |
180 message.add(args.take(numArgs) | |
181 .mappedBy((arg) => arg == null ? "null" : '"$arg"') | |
nweiz
2013/01/19 00:35:47
I really wish we had a better way of dumping strin
Bob Nystrom
2013/01/22 23:53:19
Agreed. But until then, this should cover most cas
| |
182 .join(", ")); | |
183 message.add("): part ${i - 1} was null, but part $i was not."); | |
184 throw new ArgumentError(message.toString()); | |
185 } | |
186 } | |
187 } | |
188 | |
166 /// An instantiable class for manipulating paths. Unlike the top-level | 189 /// An instantiable class for manipulating paths. Unlike the top-level |
167 /// functions, this lets you explicitly select what platform the paths will use. | 190 /// functions, this lets you explicitly select what platform the paths will use. |
168 class Builder { | 191 class Builder { |
169 /// Creates a new path builder for the given style and root directory. | 192 /// Creates a new path builder for the given style and root directory. |
170 /// | 193 /// |
171 /// If [style] is omitted, it uses the host operating system's path style. If | 194 /// If [style] is omitted, it uses the host operating system's path style. If |
172 /// [root] is omitted, it defaults to the current working directory. If [root] | 195 /// [root] is omitted, it defaults to the current working directory. If [root] |
173 /// is relative, it is considered relative to the current working directory. | 196 /// is relative, it is considered relative to the current working directory. |
174 factory Builder({Style style, String root}) { | 197 factory Builder({Style style, String root}) { |
175 if (style == null) { | 198 if (style == null) { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 /// If a part is an absolute path, then anything before that will be ignored: | 318 /// If a part is an absolute path, then anything before that will be ignored: |
296 /// | 319 /// |
297 /// builder.join('path', '/to', 'foo'); // -> '/to/foo' | 320 /// builder.join('path', '/to', 'foo'); // -> '/to/foo' |
298 /// | 321 /// |
299 String join(String part1, [String part2, String part3, String part4, | 322 String join(String part1, [String part2, String part3, String part4, |
300 String part5, String part6, String part7, String part8]) { | 323 String part5, String part6, String part7, String part8]) { |
301 var buffer = new StringBuffer(); | 324 var buffer = new StringBuffer(); |
302 var needsSeparator = false; | 325 var needsSeparator = false; |
303 | 326 |
304 var parts = [part1, part2, part3, part4, part5, part6, part7, part8]; | 327 var parts = [part1, part2, part3, part4, part5, part6, part7, part8]; |
305 for (var i = 1; i < parts.length; i++) { | 328 _validateArgList("join", parts); |
306 if (parts[i] != null && parts[i - 1] == null) { | |
307 throw new ArgumentError("join(): part ${i - 1} was null, but part $i " | |
308 "was not."); | |
309 } | |
310 } | |
311 | 329 |
312 for (var part in parts) { | 330 for (var part in parts) { |
313 if (part == null) continue; | 331 if (part == null) continue; |
314 | 332 |
315 if (this.isAbsolute(part)) { | 333 if (this.isAbsolute(part)) { |
316 // An absolute path discards everything before it. | 334 // An absolute path discards everything before it. |
317 buffer.clear(); | 335 buffer.clear(); |
318 buffer.add(part); | 336 buffer.add(part); |
319 } else { | 337 } else { |
320 if (part.length > 0 && part[0].contains(style.separatorPattern)) { | 338 if (part.length > 0 && part[0].contains(style.separatorPattern)) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
373 return parsed.toString(); | 391 return parsed.toString(); |
374 } | 392 } |
375 | 393 |
376 /// Creates a new path by appending the given path parts to the [root]. | 394 /// Creates a new path by appending the given path parts to the [root]. |
377 /// Equivalent to [join()] with [root] as the first argument. Example: | 395 /// Equivalent to [join()] with [root] as the first argument. Example: |
378 /// | 396 /// |
379 /// var builder = new Builder(root: 'root'); | 397 /// var builder = new Builder(root: 'root'); |
380 /// builder.resolve('path', 'to', 'foo'); // -> 'root/path/to/foo' | 398 /// builder.resolve('path', 'to', 'foo'); // -> 'root/path/to/foo' |
381 String resolve(String part1, [String part2, String part3, String part4, | 399 String resolve(String part1, [String part2, String part3, String part4, |
382 String part5, String part6, String part7]) { | 400 String part5, String part6, String part7]) { |
383 if (!?part2) return join(root, part1); | |
384 if (!?part3) return join(root, part1, part2); | |
385 if (!?part4) return join(root, part1, part2, part3); | |
386 if (!?part5) return join(root, part1, part2, part3, part4); | |
387 if (!?part6) return join(root, part1, part2, part3, part4, part5); | |
388 if (!?part7) return join(root, part1, part2, part3, part4, part5, part6); | |
389 return join(root, part1, part2, part3, part4, part5, part6, part7); | 401 return join(root, part1, part2, part3, part4, part5, part6, part7); |
390 } | 402 } |
391 | 403 |
392 /// Attempts to convert [path] to an equivalent relative path relative to | 404 /// Attempts to convert [path] to an equivalent relative path relative to |
393 /// [root]. | 405 /// [root]. |
394 /// | 406 /// |
395 /// var builder = new Builder(root: '/root/path'); | 407 /// var builder = new Builder(root: '/root/path'); |
396 /// builder.relative('/root/path/a/b.dart'); // -> 'a/b.dart' | 408 /// builder.relative('/root/path/a/b.dart'); // -> 'a/b.dart' |
397 /// builder.relative('/root/other.dart'); // -> '../other.dart' | 409 /// builder.relative('/root/other.dart'); // -> '../other.dart' |
398 /// | 410 /// |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
680 // If there is no dot, or it's the first character, like '.bashrc', it | 692 // If there is no dot, or it's the first character, like '.bashrc', it |
681 // doesn't count. | 693 // doesn't count. |
682 if (lastDot <= 0) return [file, '']; | 694 if (lastDot <= 0) return [file, '']; |
683 | 695 |
684 return [file.substring(0, lastDot), file.substring(lastDot)]; | 696 return [file.substring(0, lastDot), file.substring(lastDot)]; |
685 } | 697 } |
686 | 698 |
687 _ParsedPath clone() => new _ParsedPath( | 699 _ParsedPath clone() => new _ParsedPath( |
688 style, root, new List.from(parts), new List.from(separators)); | 700 style, root, new List.from(parts), new List.from(separators)); |
689 } | 701 } |
OLD | NEW |