Chromium Code Reviews| Index: utils/pub/path.dart |
| diff --git a/utils/pub/path.dart b/utils/pub/path.dart |
| index d803fd17075726750cd3c559d4731ff6478af52b..01b4c39913e88906604c5100a70c2fff0ae7c98c 100644 |
| --- a/utils/pub/path.dart |
| +++ b/utils/pub/path.dart |
| @@ -24,6 +24,12 @@ String get separator => _builder.separator; |
| /// path.absolute('foo/bar.txt'); // -> /your/current/dir/foo/bar.txt |
| String absolute(String path) => join(current, path); |
| +/// Gets the part of [path] before the last separator. |
| +/// |
| +/// path.dirname('path/to/foo.dart'); // -> 'path/to' |
| +/// path.dirname('path/to'); // -> 'to' |
| +String dirname(String path) => _builder.dirname(path); |
| + |
| /// Gets the part of [path] after the last separator. |
| /// |
| /// path.basename('path/to/foo.dart'); // -> 'foo.dart' |
| @@ -52,6 +58,18 @@ String basenameWithoutExtension(String path) => |
| /// path.extension('~/.notes.txt'); // -> '.txt' |
| String extension(String path) => _builder.extension(path); |
| +// TODO(nweiz): add a UNC example for Windows once issue 7323 is fixed. |
| +/// Returns the root of [path], if it's absolute, or `null` if it's relative. |
|
Bob Nystrom
2012/12/12 00:01:20
Generally, this library returns empty strings inst
nweiz
2012/12/12 00:50:37
I based it on the ParsedPath API, which also retur
Bob Nystrom
2012/12/12 01:02:13
That's part of the reason ParsedPath is still priv
nweiz
2012/12/12 02:45:57
Done.
|
| +/// |
| +/// // Unix |
| +/// path.rootOf('path/to/foo'); // -> null |
| +/// path.rootOf('/path/to/foo'); // -> '/' |
| +/// |
| +/// // Windows |
| +/// path.rootOf(r'path\to\foo'); // -> null |
| +/// path.rootOf(r'C:\path\to\foo'); // -> r'C:\' |
| +String rootOf(String path) => _builder.rootOf(path); |
|
Bob Nystrom
2012/12/12 00:01:20
"rootOf" -> "root", I think. I like English-like A
nweiz
2012/12/12 00:50:37
I had it as "root" originally, but that causes a n
Bob Nystrom
2012/12/12 01:02:13
maybe rootPrefix?
nweiz
2012/12/12 02:45:57
Done.
|
| + |
| /// Returns `true` if [path] is an absolute path and `false` if it is a |
| /// relative path. On POSIX systems, absolute paths start with a `/` (forward |
| /// slash). On Windows, an absolute path starts with `\\`, or a drive letter |
| @@ -78,17 +96,24 @@ bool isRelative(String path) => _builder.isRelative(path); |
| /// |
| /// path.join('path', '/to', 'foo'); // -> '/to/foo' |
| String join(String part1, [String part2, String part3, String part4, |
| - String part5, String part6, String part7, String part8]) { |
| - if (!?part2) return _builder.join(part1); |
| - if (!?part3) return _builder.join(part1, part2); |
| - if (!?part4) return _builder.join(part1, part2, part3); |
| - if (!?part5) return _builder.join(part1, part2, part3, part4); |
| - if (!?part6) return _builder.join(part1, part2, part3, part4, part5); |
| - if (!?part7) return _builder.join(part1, part2, part3, part4, part5, part6); |
| - if (!?part8) return _builder.join(part1, part2, part3, part4, part5, part6, |
| - part7); |
| - return _builder.join(part1, part2, part3, part4, part5, part6, part7, part8); |
| -} |
| + String part5, String part6, String part7, String part8]) => |
| + _builder.join(part1, part2, part3, part4, part5, part6, part7, part8); |
| + |
| +// TODO(nweiz): add a UNC example for Windows once issue 7323 is fixed. |
| +/// Splits [path] into its components using the current platform's [separator]. |
| +/// Example: |
| +/// |
| +/// path.split('path/to/foo'); // -> ['path', 'to', 'foo'] |
| +/// |
| +/// If [path] is absolute, the root directory will be the first element in the |
| +/// array. Example: |
| +/// |
| +/// // Unix |
| +/// path.split('/path/to/foo'); // -> ['/', 'path', 'to', 'foo'] |
| +/// |
| +/// // Windows |
| +/// path.split(r'C:\path\to\foo'); // -> [r'C:\', 'path', 'to', 'foo'] |
| +List<String> split(String path) => _builder.split(path); |
|
Bob Nystrom
2012/12/12 00:01:20
Heh, my preflight patch has an implementation of t
nweiz
2012/12/12 00:50:37
I like this version better, since it lists all dir
Bob Nystrom
2012/12/12 01:02:13
Ah, good call. Works for me.
|
| /// Normalizes [path], simplifying it by handling `..`, and `.`, and |
| /// removing redundant path separators whenever possible. |
| @@ -103,12 +128,17 @@ String normalize(String path) => _builder.normalize(path); |
| /// path.relative('/root/path/a/b.dart'); // -> 'a/b.dart' |
| /// path.relative('/root/other.dart'); // -> '../other.dart' |
| /// |
| +/// If the [to] argument is passed, [path] is made relative to that instead. |
|
Bob Nystrom
2012/12/12 00:01:20
I don't like reinterpreting one argument based on
nweiz
2012/12/12 00:50:37
The idea is that it returns "path" relative to "to
Bob Nystrom
2012/12/12 01:02:13
Before I accidentally lost the implementation, I w
nweiz
2012/12/12 02:45:57
That reads as "'foo/bar' relative from 'foo'" to m
Bob Nystrom
2012/12/12 04:52:33
Yeah, I like it a bit more. I read it as "get a pa
|
| +/// |
| +/// path.relative('/root/path/a/b.dart', to: '/root/path'); // -> 'a/b.dart' |
| +/// path.relative('/root/other.dart', |
| +/// to: '/root/path'); // -> '../other.dart' |
| +/// |
| /// Since there is no relative path from one drive letter to another on Windows, |
| /// this will return an absolute path in that case. |
| /// |
| -/// // Given current directory is C:\home: |
| -/// path.relative(r'D:\other'); // -> 'D:\other' |
| -String relative(String path) => _builder.relative(path); |
| +/// path.relative(r'D:\other', to: r'C:\home'); // -> 'D:\other' |
| +String relative(String path, {String to}) => _builder.relative(path, to: to); |
| /// Removes a trailing extension from the last part of [path]. |
| /// |
| @@ -149,6 +179,22 @@ class Builder { |
| /// this is `/`. On Windows, it's `\`. |
| String get separator => style.separator; |
| + /// Gets the part of [path] before the last separator. |
| + /// |
| + /// builder.dirname('path/to/foo.dart'); // -> 'path/to' |
| + /// builder.dirname('path/to'); // -> 'to' |
|
Bob Nystrom
2012/12/12 00:01:20
Show an example of what happens if there's a trail
nweiz
2012/12/12 00:50:37
I left that out intentionally because I want to ch
|
| + String dirname(String path) { |
|
Bob Nystrom
2012/12/12 00:01:20
Nit, but can you move this after basenameWithoutEx
nweiz
2012/12/12 00:50:37
Done.
|
| + var parsed = _parse(path); |
| + if (parsed.parts.isEmpty) return '.'; |
|
Bob Nystrom
2012/12/12 00:01:20
You'll need to handle absolute paths here. If ther
nweiz
2012/12/12 00:50:37
Done.
|
| + if (parsed.separators.last == '') { |
|
Bob Nystrom
2012/12/12 00:01:20
!parsed.hasTrailingSeparator
nweiz
2012/12/12 00:50:37
Done.
|
| + if (parsed.parts.length == 1) return '.'; |
|
Bob Nystrom
2012/12/12 00:01:20
I think you should be able to skip this check.
nweiz
2012/12/12 00:50:37
It dirname("a") should return ".", not "".
Bob Nystrom
2012/12/12 01:02:13
Right, but I believe toString() handles that, does
nweiz
2012/12/12 02:45:57
No, it would just return ''.
|
| + parsed.parts.removeLast(); |
| + parsed.separators.removeLast(); |
| + } |
| + parsed.separators[parsed.separators.length - 1] = ''; |
|
Bob Nystrom
2012/12/12 00:01:20
What's this for?
nweiz
2012/12/12 00:50:37
For paths with trailing separators, this makes dir
Bob Nystrom
2012/12/12 01:02:13
Yeah, consistency is what matters most to me here.
|
| + return parsed.toString(); |
| + } |
| + |
| /// Gets the part of [path] after the last separator on the builder's |
| /// platform. |
| /// |
| @@ -178,6 +224,18 @@ class Builder { |
| /// builder.extension('~/.notes.txt'); // -> '.txt' |
| String extension(String path) => _parse(path).extension; |
| + // TODO(nweiz): add a UNC example for Windows once issue 7323 is fixed. |
| + /// Returns the root of [path], if it's absolute, or `null` if it's relative. |
| + /// |
| + /// // Unix |
| + /// builder.rootOf('path/to/foo'); // -> null |
| + /// builder.rootOf('/path/to/foo'); // -> '/' |
| + /// |
| + /// // Windows |
| + /// builder.rootOf(r'path\to\foo'); // -> null |
| + /// builder.rootOf(r'C:\path\to\foo'); // -> r'C:\' |
| + String rootOf(String path) => _parse(path).root; |
| + |
| /// Returns `true` if [path] is an absolute path and `false` if it is a |
| /// relative path. On POSIX systems, absolute paths start with a `/` (forward |
| /// slash). On Windows, an absolute path starts with `\\`, or a drive letter |
| @@ -208,8 +266,15 @@ class Builder { |
| var buffer = new StringBuffer(); |
| var needsSeparator = false; |
| - addPart(condition, part) { |
| - if (!condition) return; |
| + var parts = [part1, part2, part3, part4, part5, part6, part7, part8]; |
| + for (var i = 1; i < parts.length; i++) { |
| + if (parts[i] == null || parts[i - 1] != null) continue; |
|
Bob Nystrom
2012/12/12 00:01:20
I'd find this more intuitive if you flipped the lo
nweiz
2012/12/12 00:50:37
Done.
|
| + throw new ArgumentError("join(): part ${i - 1} was null, but part $i was " |
| + "not."); |
| + } |
| + |
| + for (var part in parts) { |
| + if (part == null) continue; |
| if (this.isAbsolute(part)) { |
| // An absolute path discards everything before it. |
| @@ -231,18 +296,31 @@ class Builder { |
| !style.separatorPattern.hasMatch(part[part.length - 1]); |
| } |
| - addPart(true, part1); |
| - addPart(?part2, part2); |
| - addPart(?part3, part3); |
| - addPart(?part4, part4); |
| - addPart(?part5, part5); |
| - addPart(?part6, part6); |
| - addPart(?part7, part7); |
| - addPart(?part8, part8); |
| - |
| return buffer.toString(); |
| } |
| + // TODO(nweiz): add a UNC example for Windows once issue 7323 is fixed. |
| + /// Splits [path] into its components using the current platform's [separator]. |
|
Bob Nystrom
2012/12/12 00:01:20
Long line.
nweiz
2012/12/12 00:50:37
Done.
|
| + /// Example: |
| + /// |
| + /// builder.split('path/to/foo'); // -> ['path', 'to', 'foo'] |
| + /// |
| + /// If [path] is absolute, the root directory will be the first element in the |
| + /// array. Example: |
| + /// |
| + /// // Unix |
| + /// builder.split('/path/to/foo'); // -> ['/', 'path', 'to', 'foo'] |
| + /// |
| + /// // Windows |
| + /// builder.split(r'C:\path\to\foo'); // -> [r'C:\', 'path', 'to', 'foo'] |
| + List<String> split(String path) { |
| + var parsed = _parse(path); |
| + // Filter out empty parts that exist due to multiple separators in a row. |
| + parsed.parts = parsed.parts.filter((part) => part != ''); |
| + if (parsed.root != null) parsed.parts.insertRange(0, 1, parsed.root); |
| + return parsed.parts; |
| + } |
| + |
| /// Normalizes [path], simplifying it by handling `..`, and `.`, and |
| /// removing redundant path separators whenever possible. |
| /// |
| @@ -278,17 +356,23 @@ class Builder { |
| /// builder.relative('/root/path/a/b.dart'); // -> 'a/b.dart' |
| /// builder.relative('/root/other.dart'); // -> '../other.dart' |
| /// |
| + /// If the [to] argument is passed, [path] is made relative to that instead. |
| + /// |
| + /// builder.relative('/root/path/a/b.dart', |
| + /// to: '/root/path'); // -> 'a/b.dart' |
| + /// builder.relative('/root/other.dart', |
| + /// to: '/root/path'); // -> '../other.dart' |
| + /// |
| /// Since there is no relative path from one drive letter to another on |
| /// Windows, this will return an absolute path in that case. |
| /// |
| - /// var builder = new Builder(root: r'C:\home'); |
| - /// builder.relative(r'D:\other'); // -> 'D:\other' |
| - String relative(String path) { |
| + /// builder.relative(r'D:\other', to: r'C:\other'); // -> 'D:\other' |
| + String relative(String path, {String to}) { |
| if (path == '') return '.'; |
| // If the base path is relative, resolve it relative to the current |
| // directory. |
| - var base = root; |
| + var base = to == null ? root : to; |
| if (this.isRelative(base)) base = absolute(base); |
| // If the given path is relative, resolve it relative to the base. |