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

Unified Diff: utils/pub/path.dart

Issue 11471048: Revise path library. (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
« no previous file with comments | « utils/pub/io.dart ('k') | utils/pub/validator/name.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utils/pub/path.dart
diff --git a/utils/pub/path.dart b/utils/pub/path.dart
index 3b889d380654bd50e2d75c97e3e8f3e5964bfc15..3f36b862baa4b35d4451567c259761ecafe22eaf 100644
--- a/utils/pub/path.dart
+++ b/utils/pub/path.dart
@@ -24,42 +24,44 @@ 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 file extension of [path]; the portion after the last `.` in the
-/// [basename] of the path.
+/// Gets the part of [path] after the last separator.
+///
+/// path.basename('path/to/foo.dart'); // -> 'foo.dart'
+/// path.basename('path/to'); // -> 'to'
+String basename(String path) => _builder.basename(path);
+
+/// Gets the part of [path] after the last separator, and without any trailing
+/// file extension.
+///
+/// path.basenameWithoutExtension('path/to/foo.dart'); // -> 'foo'
+String basenameWithoutExtension(String path) =>
+ _builder.basenameWithoutExtension(path);
+
+/// Gets the file extension of [path]: the portion of [basename] from the last
+/// `.` to the end (including the `.` itself).
///
/// path.extension('path/to/foo.dart'); // -> '.dart'
/// path.extension('path/to/foo'); // -> ''
/// path.extension('path.to/foo'); // -> ''
/// path.extension('path/to/foo.dart.js'); // -> '.js'
///
-/// If the file name starts with a `.`, then it is not considered an extension:
+/// If the file name starts with a `.`, then that is not considered the
+/// extension:
///
-/// path.extension('~/.bashrc'); // -> ''
+/// path.extension('~/.bashrc'); // -> ''
+/// path.extension('~/.notes.txt'); // -> '.txt'
String extension(String path) => _builder.extension(path);
-/// Gets the part of [path] after the last separator on the current platform.
-///
-/// path.filename('path/to/foo.dart'); // -> 'foo.dart'
-/// path.filename('path/to'); // -> 'to'
-String filename(String path) => _builder.filename(path);
-
-/// Gets the part of [path] after the last separator on the current platform,
-/// and without any trailing file extension.
-///
-/// path.filenameWithoutExtension('path/to/foo.dart'); // -> 'foo'
-String filenameWithoutExtension(String path) =>
- _builder.filenameWithoutExtension(path);
-
/// Returns `true` if [path] is an absolute path and `false` if it is a
-/// relative path. On Mac and Unix systems, relative paths start with a `/`
-/// (forward slash). On Windows, an absolute path starts with `\\`, or a drive
-/// letter followed by `:/` or `:\`.
+/// relative path. On POSIX systems, absolute paths start with a `/` (forward
+/// slash). On Windows, an absolute path starts with `\\`, or a drive letter
+/// followed by `:/` or `:\`.
bool isAbsolute(String path) => _builder.isAbsolute(path);
/// Returns `true` if [path] is a relative path and `false` if it is absolute.
-/// On Mac and Unix systems, relative paths start with a `/` (forward slash).
-/// On Windows, an absolute path starts with `\\`, or a drive letter followed
-/// by `:/` or `:\`.
+/// On POSIX systems, absolute paths start with a `/` (forward slash). On
+/// Windows, an absolute path starts with `\\`, or a drive letter followed by
+/// `:/` or `:\`.
bool isRelative(String path) => _builder.isRelative(path);
/// Joins the given path parts into a single path using the current platform's
@@ -75,7 +77,6 @@ bool isRelative(String path) => _builder.isRelative(path);
/// If a part is an absolute path, then anything before that will be ignored:
///
/// 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);
@@ -95,11 +96,18 @@ String join(String part1, [String part2, String part3, String part4,
/// path.normalize('path/./to/..//file.text'); // -> 'path/file.txt'
String normalize(String path) => _builder.normalize(path);
-/// Converts [path] to an equivalent relative path from the current directory.
+/// Attempts to convert [path] to an equivalent relative path from the current
+/// directory.
///
/// // Given current directory is /root/path:
/// path.relative('/root/path/a/b.dart'); // -> 'a/b.dart'
/// path.relative('/root/other.dart'); // -> '../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);
/// Removes a trailing extension from the last part of [path].
@@ -113,7 +121,8 @@ class Builder {
/// Creates a new path builder for the given style and root directory.
///
/// If [style] is omitted, it uses the host operating system's path style. If
- /// [root] is omitted, it defaults to the current working directory.
+ /// [root] is omitted, it defaults to the current working directory. If [root]
+ /// is relative, it is considered relative to the current working directory.
factory Builder({Style style, String root}) {
if (style == null) {
if (io.Platform.operatingSystem == 'windows') {
@@ -123,7 +132,7 @@ class Builder {
}
}
- if (root == null) root = new io.Directory.current().path;
+ if (root == null) root = current;
return new Builder._(style, root);
}
@@ -140,8 +149,22 @@ class Builder {
/// this is `/`. On Windows, it's `\`.
String get separator => style.separator;
- /// Gets the file extension of [path]; the portion after the last `.` in the
- /// [basename] of the path.
+ /// Gets the part of [path] after the last separator on the builder's
+ /// platform.
+ ///
+ /// builder.basename('path/to/foo.dart'); // -> 'foo.dart'
+ /// builder.basename('path/to'); // -> 'to'
+ String basename(String path) => _parse(path).basename;
+
+ /// Gets the part of [path] after the last separator on the builder's
+ /// platform, and without any trailing file extension.
+ ///
+ /// builder.basenameWithoutExtension('path/to/foo.dart'); // -> 'foo'
+ String basenameWithoutExtension(String path) =>
+ _parse(path).basenameWithoutExtension;
+
+ /// Gets the file extension of [path]: the portion of [basename] from the last
+ /// `.` to the end (including the `.` itself).
///
/// builder.extension('path/to/foo.dart'); // -> '.dart'
/// builder.extension('path/to/foo'); // -> ''
@@ -151,33 +174,20 @@ class Builder {
/// If the file name starts with a `.`, then it is not considered an
/// extension:
///
- /// builder.extension('~/.bashrc'); // -> ''
+ /// builder.extension('~/.bashrc'); // -> ''
+ /// builder.extension('~/.notes.txt'); // -> '.txt'
String extension(String path) => _parse(path).extension;
- /// Gets the part of [path] after the last separator on the builder's
- /// platform.
- ///
- /// builder.filename('path/to/foo.dart'); // -> 'foo.dart'
- /// builder.filename('path/to'); // -> 'to'
- String filename(String path) => _parse(path).filename;
-
- /// Gets the part of [path] after the last separator on the builder's
- /// platform, and without any trailing file extension.
- ///
- /// builder.filenameWithoutExtension('path/to/foo.dart'); // -> 'foo'
- String filenameWithoutExtension(String path) =>
- _parse(path).filenameWithoutExtension;
-
/// Returns `true` if [path] is an absolute path and `false` if it is a
- /// relative path. On Mac and Unix systems, relative paths start with a `/`
- /// (forward slash). On Windows, an absolute path starts with `\\`, or a drive
- /// letter followed by `:/` or `:\`.
+ /// relative path. On POSIX systems, absolute paths start with a `/` (forward
+ /// slash). On Windows, an absolute path starts with `\\`, or a drive letter
+ /// followed by `:/` or `:\`.
bool isAbsolute(String path) => _parse(path).isAbsolute;
/// Returns `true` if [path] is a relative path and `false` if it is absolute.
- /// On Mac and Unix systems, relative paths start with a `/` (forward slash).
- /// On Windows, an absolute path starts with `\\`, or a drive letter followed
- /// by `:/` or `:\`.
+ /// On POSIX systems, absolute paths start with a `/` (forward slash). On
+ /// Windows, an absolute path starts with `\\`, or a drive letter followed by
+ /// `:/` or `:\`.
bool isRelative(String path) => !isAbsolute(path);
/// Joins the given path parts into a single path. Example:
@@ -249,7 +259,7 @@ class Builder {
/// Equivalent to [join()] with [root] as the first argument. Example:
///
/// var builder = new Builder(root: 'root');
- /// builder.join('path', 'to', 'foo'); // -> 'root/path/to/foo'
+ /// builder.resolve('path', 'to', 'foo'); // -> 'root/path/to/foo'
String resolve(String part1, [String part2, String part3, String part4,
String part5, String part6, String part7]) {
if (!?part2) return join(root, part1);
@@ -261,19 +271,28 @@ class Builder {
return join(root, part1, part2, part3, part4, part5, part6, part7);
}
- /// Converts [path] to an equivalent relative path starting at [root].
+ /// Attempts to convert [path] to an equivalent relative path relative to
+ /// [root].
///
/// var builder = new Builder(root: '/root/path');
/// builder.relative('/root/path/a/b.dart'); // -> 'a/b.dart'
/// builder.relative('/root/other.dart'); // -> '../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) {
+ if (path == '') return '.';
+
// If the base path is relative, resolve it relative to the current
// directory.
var base = root;
if (this.isRelative(base)) base = absolute(base);
// If the given path is relative, resolve it relative to the base.
- path = this.join(base, path);
+ if (this.isRelative(path)) return this.normalize(path);
var baseParsed = _parse(base)..normalize();
var pathParsed = _parse(path)..normalize();
@@ -281,11 +300,13 @@ class Builder {
// If the root prefixes don't match (for example, different drive letters
// on Windows), then there is no relative path, so just return the absolute
// one.
+ // TODO(rnystrom): Drive letters are case-insentive on Windows. Should
+ // handle "C:\" and "c:\" being the same root.
if (baseParsed.root != pathParsed.root) return pathParsed.toString();
// Strip off their common prefix.
- while (baseParsed.parts.length > 0 && pathParsed.parts.length > 0) {
- if (baseParsed.parts[0] != pathParsed.parts[0]) break;
+ while (baseParsed.parts.length > 0 && pathParsed.parts.length > 0 &&
+ baseParsed.parts[0] == pathParsed.parts[0]) {
baseParsed.parts.removeAt(0);
baseParsed.separators.removeAt(0);
pathParsed.parts.removeAt(0);
@@ -312,14 +333,9 @@ class Builder {
///
/// builder.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
String withoutExtension(String path) {
- var lastSeparator = path.lastIndexOf(separator);
- var lastDot = path.lastIndexOf('.');
-
- // Ignore '.' in anything but the last component.
- if (lastSeparator != -1 && lastDot <= lastSeparator + 1) lastDot = -1;
-
- if (lastDot <= 0) return path;
- return path.substring(0, lastDot);
+ var parsed = _parse(path);
+ parsed.extension = null;
+ return parsed.toString();
}
_ParsedPath _parse(String path) {
@@ -373,10 +389,13 @@ class Style {
/// Windows paths use "\" (backslash) as separators. Absolute paths start with
/// a drive letter followed by a colon (example, "C:") or two backslashes
/// ("\\") for UNC paths.
+ // TODO(rnystrom): The UNC root prefix should include the drive name too, not
+ // just the "\\".
static final windows = new Style._('windows', '\\', r'[/\\]',
r'\\\\|[a-zA-Z]:[/\\]');
- Style._(this.name, this.separator, String separatorPattern, String rootPattern)
+ Style._(this.name, this.separator, String separatorPattern,
+ String rootPattern)
: separatorPattern = new RegExp(separatorPattern),
_rootPattern = new RegExp('^$rootPattern');
@@ -442,13 +461,13 @@ class _ParsedPath {
_ParsedPath(this.style, this.root, this.parts, this.separators,
this.extension);
- String get filename {
+ String get basename {
if (parts.length == 0) return extension;
if (hasTrailingSeparator) return '';
return '${parts.last}$extension';
}
- String get filenameWithoutExtension {
+ String get basenameWithoutExtension {
if (parts.length == 0) return '';
if (hasTrailingSeparator) return '';
return parts.last;
« no previous file with comments | « utils/pub/io.dart ('k') | utils/pub/validator/name.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698