Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Unified Diff: utils/pub/path.dart

Issue 11553005: Move path-manipulation code from io.dart into path.dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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.

Powered by Google App Engine
This is Rietveld 408576698