Chromium Code Reviews| 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 |
| 11 /// functional interface and not require users to create one. | 11 /// functional interface and not require users to create one. |
| 12 final _builder = new Builder(); | 12 final _builder = new Builder(); |
| 13 | 13 |
| 14 /// Gets the path to the current working directory. | 14 /// Gets the path to the current working directory. |
| 15 String get current => new io.Directory.current().path; | 15 String get current => new io.Directory.current().path; |
| 16 | 16 |
| 17 /// Gets the path separator for the current platform. On Mac and Linux, this | 17 /// Gets the path separator for the current platform. On Mac and Linux, this |
| 18 /// is `/`. On Windows, it's `\`. | 18 /// is `/`. On Windows, it's `\`. |
| 19 String get separator => _builder.separator; | 19 String get separator => _builder.separator; |
| 20 | 20 |
| 21 /// Converts [path] to an absolute path by resolving it relative to the current | 21 /// Converts [path] to an absolute path by resolving it relative to the current |
| 22 /// working directory. If [path] is already an absolute path, just returns it. | 22 /// working directory. If [path] is already an absolute path, just returns it. |
| 23 /// | 23 /// |
| 24 /// path.absolute('foo/bar.txt'); // -> /your/current/dir/foo/bar.txt | 24 /// path.absolute('foo/bar.txt'); // -> /your/current/dir/foo/bar.txt |
| 25 String absolute(String path) => join(current, path); | 25 String absolute(String path) => join(current, path); |
| 26 | 26 |
| 27 /// Gets the part of [path] before the last separator. | |
| 28 /// | |
| 29 /// path.dirname('path/to/foo.dart'); // -> 'path/to' | |
| 30 /// path.dirname('path/to'); // -> 'to' | |
| 31 String dirname(String path) => _builder.dirname(path); | |
| 32 | |
| 27 /// Gets the part of [path] after the last separator. | 33 /// Gets the part of [path] after the last separator. |
| 28 /// | 34 /// |
| 29 /// path.basename('path/to/foo.dart'); // -> 'foo.dart' | 35 /// path.basename('path/to/foo.dart'); // -> 'foo.dart' |
| 30 /// path.basename('path/to'); // -> 'to' | 36 /// path.basename('path/to'); // -> 'to' |
| 31 String basename(String path) => _builder.basename(path); | 37 String basename(String path) => _builder.basename(path); |
| 32 | 38 |
| 33 /// Gets the part of [path] after the last separator, and without any trailing | 39 /// Gets the part of [path] after the last separator, and without any trailing |
| 34 /// file extension. | 40 /// file extension. |
| 35 /// | 41 /// |
| 36 /// path.basenameWithoutExtension('path/to/foo.dart'); // -> 'foo' | 42 /// path.basenameWithoutExtension('path/to/foo.dart'); // -> 'foo' |
| 37 String basenameWithoutExtension(String path) => | 43 String basenameWithoutExtension(String path) => |
| 38 _builder.basenameWithoutExtension(path); | 44 _builder.basenameWithoutExtension(path); |
| 39 | 45 |
| 40 /// Gets the file extension of [path]: the portion of [basename] from the last | 46 /// Gets the file extension of [path]: the portion of [basename] from the last |
| 41 /// `.` to the end (including the `.` itself). | 47 /// `.` to the end (including the `.` itself). |
| 42 /// | 48 /// |
| 43 /// path.extension('path/to/foo.dart'); // -> '.dart' | 49 /// path.extension('path/to/foo.dart'); // -> '.dart' |
| 44 /// path.extension('path/to/foo'); // -> '' | 50 /// path.extension('path/to/foo'); // -> '' |
| 45 /// path.extension('path.to/foo'); // -> '' | 51 /// path.extension('path.to/foo'); // -> '' |
| 46 /// path.extension('path/to/foo.dart.js'); // -> '.js' | 52 /// path.extension('path/to/foo.dart.js'); // -> '.js' |
| 47 /// | 53 /// |
| 48 /// If the file name starts with a `.`, then that is not considered the | 54 /// If the file name starts with a `.`, then that is not considered the |
| 49 /// extension: | 55 /// extension: |
| 50 /// | 56 /// |
| 51 /// path.extension('~/.bashrc'); // -> '' | 57 /// path.extension('~/.bashrc'); // -> '' |
| 52 /// path.extension('~/.notes.txt'); // -> '.txt' | 58 /// path.extension('~/.notes.txt'); // -> '.txt' |
| 53 String extension(String path) => _builder.extension(path); | 59 String extension(String path) => _builder.extension(path); |
| 54 | 60 |
| 61 // TODO(nweiz): add a UNC example for Windows once issue 7323 is fixed. | |
| 62 /// 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.
| |
| 63 /// | |
| 64 /// // Unix | |
| 65 /// path.rootOf('path/to/foo'); // -> null | |
| 66 /// path.rootOf('/path/to/foo'); // -> '/' | |
| 67 /// | |
| 68 /// // Windows | |
| 69 /// path.rootOf(r'path\to\foo'); // -> null | |
| 70 /// path.rootOf(r'C:\path\to\foo'); // -> r'C:\' | |
| 71 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.
| |
| 72 | |
| 55 /// Returns `true` if [path] is an absolute path and `false` if it is a | 73 /// Returns `true` if [path] is an absolute path and `false` if it is a |
| 56 /// relative path. On POSIX systems, absolute paths start with a `/` (forward | 74 /// relative path. On POSIX systems, absolute paths start with a `/` (forward |
| 57 /// slash). On Windows, an absolute path starts with `\\`, or a drive letter | 75 /// slash). On Windows, an absolute path starts with `\\`, or a drive letter |
| 58 /// followed by `:/` or `:\`. | 76 /// followed by `:/` or `:\`. |
| 59 bool isAbsolute(String path) => _builder.isAbsolute(path); | 77 bool isAbsolute(String path) => _builder.isAbsolute(path); |
| 60 | 78 |
| 61 /// Returns `true` if [path] is a relative path and `false` if it is absolute. | 79 /// Returns `true` if [path] is a relative path and `false` if it is absolute. |
| 62 /// On POSIX systems, absolute paths start with a `/` (forward slash). On | 80 /// On POSIX systems, absolute paths start with a `/` (forward slash). On |
| 63 /// Windows, an absolute path starts with `\\`, or a drive letter followed by | 81 /// Windows, an absolute path starts with `\\`, or a drive letter followed by |
| 64 /// `:/` or `:\`. | 82 /// `:/` or `:\`. |
| 65 bool isRelative(String path) => _builder.isRelative(path); | 83 bool isRelative(String path) => _builder.isRelative(path); |
| 66 | 84 |
| 67 /// Joins the given path parts into a single path using the current platform's | 85 /// Joins the given path parts into a single path using the current platform's |
| 68 /// [separator]. Example: | 86 /// [separator]. Example: |
| 69 /// | 87 /// |
| 70 /// path.join('path', 'to', 'foo'); // -> 'path/to/foo' | 88 /// path.join('path', 'to', 'foo'); // -> 'path/to/foo' |
| 71 /// | 89 /// |
| 72 /// If any part ends in a path separator, then a redundant separator will not | 90 /// If any part ends in a path separator, then a redundant separator will not |
| 73 /// be added: | 91 /// be added: |
| 74 /// | 92 /// |
| 75 /// path.join('path/', 'to', 'foo'); // -> 'path/to/foo | 93 /// path.join('path/', 'to', 'foo'); // -> 'path/to/foo |
| 76 /// | 94 /// |
| 77 /// If a part is an absolute path, then anything before that will be ignored: | 95 /// If a part is an absolute path, then anything before that will be ignored: |
| 78 /// | 96 /// |
| 79 /// path.join('path', '/to', 'foo'); // -> '/to/foo' | 97 /// path.join('path', '/to', 'foo'); // -> '/to/foo' |
| 80 String join(String part1, [String part2, String part3, String part4, | 98 String join(String part1, [String part2, String part3, String part4, |
| 81 String part5, String part6, String part7, String part8]) { | 99 String part5, String part6, String part7, String part8]) => |
| 82 if (!?part2) return _builder.join(part1); | 100 _builder.join(part1, part2, part3, part4, part5, part6, part7, part8); |
| 83 if (!?part3) return _builder.join(part1, part2); | 101 |
| 84 if (!?part4) return _builder.join(part1, part2, part3); | 102 // TODO(nweiz): add a UNC example for Windows once issue 7323 is fixed. |
| 85 if (!?part5) return _builder.join(part1, part2, part3, part4); | 103 /// Splits [path] into its components using the current platform's [separator]. |
| 86 if (!?part6) return _builder.join(part1, part2, part3, part4, part5); | 104 /// Example: |
| 87 if (!?part7) return _builder.join(part1, part2, part3, part4, part5, part6); | 105 /// |
| 88 if (!?part8) return _builder.join(part1, part2, part3, part4, part5, part6, | 106 /// path.split('path/to/foo'); // -> ['path', 'to', 'foo'] |
| 89 part7); | 107 /// |
| 90 return _builder.join(part1, part2, part3, part4, part5, part6, part7, part8); | 108 /// If [path] is absolute, the root directory will be the first element in the |
| 91 } | 109 /// array. Example: |
| 110 /// | |
| 111 /// // Unix | |
| 112 /// path.split('/path/to/foo'); // -> ['/', 'path', 'to', 'foo'] | |
| 113 /// | |
| 114 /// // Windows | |
| 115 /// path.split(r'C:\path\to\foo'); // -> [r'C:\', 'path', 'to', 'foo'] | |
| 116 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.
| |
| 92 | 117 |
| 93 /// Normalizes [path], simplifying it by handling `..`, and `.`, and | 118 /// Normalizes [path], simplifying it by handling `..`, and `.`, and |
| 94 /// removing redundant path separators whenever possible. | 119 /// removing redundant path separators whenever possible. |
| 95 /// | 120 /// |
| 96 /// path.normalize('path/./to/..//file.text'); // -> 'path/file.txt' | 121 /// path.normalize('path/./to/..//file.text'); // -> 'path/file.txt' |
| 97 String normalize(String path) => _builder.normalize(path); | 122 String normalize(String path) => _builder.normalize(path); |
| 98 | 123 |
| 99 /// Attempts to convert [path] to an equivalent relative path from the current | 124 /// Attempts to convert [path] to an equivalent relative path from the current |
| 100 /// directory. | 125 /// directory. |
| 101 /// | 126 /// |
| 102 /// // Given current directory is /root/path: | 127 /// // Given current directory is /root/path: |
| 103 /// path.relative('/root/path/a/b.dart'); // -> 'a/b.dart' | 128 /// path.relative('/root/path/a/b.dart'); // -> 'a/b.dart' |
| 104 /// path.relative('/root/other.dart'); // -> '../other.dart' | 129 /// path.relative('/root/other.dart'); // -> '../other.dart' |
| 105 /// | 130 /// |
| 131 /// 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
| |
| 132 /// | |
| 133 /// path.relative('/root/path/a/b.dart', to: '/root/path'); // -> 'a/b.dart' | |
| 134 /// path.relative('/root/other.dart', | |
| 135 /// to: '/root/path'); // -> '../other.dart' | |
| 136 /// | |
| 106 /// Since there is no relative path from one drive letter to another on Windows, | 137 /// Since there is no relative path from one drive letter to another on Windows, |
| 107 /// this will return an absolute path in that case. | 138 /// this will return an absolute path in that case. |
| 108 /// | 139 /// |
| 109 /// // Given current directory is C:\home: | 140 /// path.relative(r'D:\other', to: r'C:\home'); // -> 'D:\other' |
| 110 /// path.relative(r'D:\other'); // -> 'D:\other' | 141 String relative(String path, {String to}) => _builder.relative(path, to: to); |
| 111 String relative(String path) => _builder.relative(path); | |
| 112 | 142 |
| 113 /// Removes a trailing extension from the last part of [path]. | 143 /// Removes a trailing extension from the last part of [path]. |
| 114 /// | 144 /// |
| 115 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' | 145 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' |
| 116 String withoutExtension(String path) => _builder.withoutExtension(path); | 146 String withoutExtension(String path) => _builder.withoutExtension(path); |
| 117 | 147 |
| 118 /// An instantiable class for manipulating paths. Unlike the top-level | 148 /// An instantiable class for manipulating paths. Unlike the top-level |
| 119 /// functions, this lets you explicitly select what platform the paths will use. | 149 /// functions, this lets you explicitly select what platform the paths will use. |
| 120 class Builder { | 150 class Builder { |
| 121 /// Creates a new path builder for the given style and root directory. | 151 /// Creates a new path builder for the given style and root directory. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 142 /// The style of path that this builder works with. | 172 /// The style of path that this builder works with. |
| 143 final Style style; | 173 final Style style; |
| 144 | 174 |
| 145 /// The root directory that relative paths will be relative to. | 175 /// The root directory that relative paths will be relative to. |
| 146 final String root; | 176 final String root; |
| 147 | 177 |
| 148 /// Gets the path separator for the builder's [style]. On Mac and Linux, | 178 /// Gets the path separator for the builder's [style]. On Mac and Linux, |
| 149 /// this is `/`. On Windows, it's `\`. | 179 /// this is `/`. On Windows, it's `\`. |
| 150 String get separator => style.separator; | 180 String get separator => style.separator; |
| 151 | 181 |
| 182 /// Gets the part of [path] before the last separator. | |
| 183 /// | |
| 184 /// builder.dirname('path/to/foo.dart'); // -> 'path/to' | |
| 185 /// 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
| |
| 186 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.
| |
| 187 var parsed = _parse(path); | |
| 188 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.
| |
| 189 if (parsed.separators.last == '') { | |
|
Bob Nystrom
2012/12/12 00:01:20
!parsed.hasTrailingSeparator
nweiz
2012/12/12 00:50:37
Done.
| |
| 190 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 ''.
| |
| 191 parsed.parts.removeLast(); | |
| 192 parsed.separators.removeLast(); | |
| 193 } | |
| 194 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.
| |
| 195 return parsed.toString(); | |
| 196 } | |
| 197 | |
| 152 /// Gets the part of [path] after the last separator on the builder's | 198 /// Gets the part of [path] after the last separator on the builder's |
| 153 /// platform. | 199 /// platform. |
| 154 /// | 200 /// |
| 155 /// builder.basename('path/to/foo.dart'); // -> 'foo.dart' | 201 /// builder.basename('path/to/foo.dart'); // -> 'foo.dart' |
| 156 /// builder.basename('path/to'); // -> 'to' | 202 /// builder.basename('path/to'); // -> 'to' |
| 157 String basename(String path) => _parse(path).basename; | 203 String basename(String path) => _parse(path).basename; |
| 158 | 204 |
| 159 /// Gets the part of [path] after the last separator on the builder's | 205 /// Gets the part of [path] after the last separator on the builder's |
| 160 /// platform, and without any trailing file extension. | 206 /// platform, and without any trailing file extension. |
| 161 /// | 207 /// |
| 162 /// builder.basenameWithoutExtension('path/to/foo.dart'); // -> 'foo' | 208 /// builder.basenameWithoutExtension('path/to/foo.dart'); // -> 'foo' |
| 163 String basenameWithoutExtension(String path) => | 209 String basenameWithoutExtension(String path) => |
| 164 _parse(path).basenameWithoutExtension; | 210 _parse(path).basenameWithoutExtension; |
| 165 | 211 |
| 166 /// Gets the file extension of [path]: the portion of [basename] from the last | 212 /// Gets the file extension of [path]: the portion of [basename] from the last |
| 167 /// `.` to the end (including the `.` itself). | 213 /// `.` to the end (including the `.` itself). |
| 168 /// | 214 /// |
| 169 /// builder.extension('path/to/foo.dart'); // -> '.dart' | 215 /// builder.extension('path/to/foo.dart'); // -> '.dart' |
| 170 /// builder.extension('path/to/foo'); // -> '' | 216 /// builder.extension('path/to/foo'); // -> '' |
| 171 /// builder.extension('path.to/foo'); // -> '' | 217 /// builder.extension('path.to/foo'); // -> '' |
| 172 /// builder.extension('path/to/foo.dart.js'); // -> '.js' | 218 /// builder.extension('path/to/foo.dart.js'); // -> '.js' |
| 173 /// | 219 /// |
| 174 /// If the file name starts with a `.`, then it is not considered an | 220 /// If the file name starts with a `.`, then it is not considered an |
| 175 /// extension: | 221 /// extension: |
| 176 /// | 222 /// |
| 177 /// builder.extension('~/.bashrc'); // -> '' | 223 /// builder.extension('~/.bashrc'); // -> '' |
| 178 /// builder.extension('~/.notes.txt'); // -> '.txt' | 224 /// builder.extension('~/.notes.txt'); // -> '.txt' |
| 179 String extension(String path) => _parse(path).extension; | 225 String extension(String path) => _parse(path).extension; |
| 180 | 226 |
| 227 // TODO(nweiz): add a UNC example for Windows once issue 7323 is fixed. | |
| 228 /// Returns the root of [path], if it's absolute, or `null` if it's relative. | |
| 229 /// | |
| 230 /// // Unix | |
| 231 /// builder.rootOf('path/to/foo'); // -> null | |
| 232 /// builder.rootOf('/path/to/foo'); // -> '/' | |
| 233 /// | |
| 234 /// // Windows | |
| 235 /// builder.rootOf(r'path\to\foo'); // -> null | |
| 236 /// builder.rootOf(r'C:\path\to\foo'); // -> r'C:\' | |
| 237 String rootOf(String path) => _parse(path).root; | |
| 238 | |
| 181 /// Returns `true` if [path] is an absolute path and `false` if it is a | 239 /// Returns `true` if [path] is an absolute path and `false` if it is a |
| 182 /// relative path. On POSIX systems, absolute paths start with a `/` (forward | 240 /// relative path. On POSIX systems, absolute paths start with a `/` (forward |
| 183 /// slash). On Windows, an absolute path starts with `\\`, or a drive letter | 241 /// slash). On Windows, an absolute path starts with `\\`, or a drive letter |
| 184 /// followed by `:/` or `:\`. | 242 /// followed by `:/` or `:\`. |
| 185 bool isAbsolute(String path) => _parse(path).isAbsolute; | 243 bool isAbsolute(String path) => _parse(path).isAbsolute; |
| 186 | 244 |
| 187 /// Returns `true` if [path] is a relative path and `false` if it is absolute. | 245 /// Returns `true` if [path] is a relative path and `false` if it is absolute. |
| 188 /// On POSIX systems, absolute paths start with a `/` (forward slash). On | 246 /// On POSIX systems, absolute paths start with a `/` (forward slash). On |
| 189 /// Windows, an absolute path starts with `\\`, or a drive letter followed by | 247 /// Windows, an absolute path starts with `\\`, or a drive letter followed by |
| 190 /// `:/` or `:\`. | 248 /// `:/` or `:\`. |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 201 /// | 259 /// |
| 202 /// If a part is an absolute path, then anything before that will be ignored: | 260 /// If a part is an absolute path, then anything before that will be ignored: |
| 203 /// | 261 /// |
| 204 /// builder.join('path', '/to', 'foo'); // -> '/to/foo' | 262 /// builder.join('path', '/to', 'foo'); // -> '/to/foo' |
| 205 /// | 263 /// |
| 206 String join(String part1, [String part2, String part3, String part4, | 264 String join(String part1, [String part2, String part3, String part4, |
| 207 String part5, String part6, String part7, String part8]) { | 265 String part5, String part6, String part7, String part8]) { |
| 208 var buffer = new StringBuffer(); | 266 var buffer = new StringBuffer(); |
| 209 var needsSeparator = false; | 267 var needsSeparator = false; |
| 210 | 268 |
| 211 addPart(condition, part) { | 269 var parts = [part1, part2, part3, part4, part5, part6, part7, part8]; |
| 212 if (!condition) return; | 270 for (var i = 1; i < parts.length; i++) { |
| 271 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.
| |
| 272 throw new ArgumentError("join(): part ${i - 1} was null, but part $i was " | |
| 273 "not."); | |
| 274 } | |
| 275 | |
| 276 for (var part in parts) { | |
| 277 if (part == null) continue; | |
| 213 | 278 |
| 214 if (this.isAbsolute(part)) { | 279 if (this.isAbsolute(part)) { |
| 215 // An absolute path discards everything before it. | 280 // An absolute path discards everything before it. |
| 216 buffer.clear(); | 281 buffer.clear(); |
| 217 buffer.add(part); | 282 buffer.add(part); |
| 218 } else { | 283 } else { |
| 219 if (part.length > 0 && style.separatorPattern.hasMatch(part[0])) { | 284 if (part.length > 0 && style.separatorPattern.hasMatch(part[0])) { |
| 220 // The part starts with a separator, so we don't need to add one. | 285 // The part starts with a separator, so we don't need to add one. |
| 221 } else if (needsSeparator) { | 286 } else if (needsSeparator) { |
| 222 buffer.add(separator); | 287 buffer.add(separator); |
| 223 } | 288 } |
| 224 | 289 |
| 225 buffer.add(part); | 290 buffer.add(part); |
| 226 } | 291 } |
| 227 | 292 |
| 228 // Unless this part ends with a separator, we'll need to add one before | 293 // Unless this part ends with a separator, we'll need to add one before |
| 229 // the next part. | 294 // the next part. |
| 230 needsSeparator = part.length > 0 && | 295 needsSeparator = part.length > 0 && |
| 231 !style.separatorPattern.hasMatch(part[part.length - 1]); | 296 !style.separatorPattern.hasMatch(part[part.length - 1]); |
| 232 } | 297 } |
| 233 | 298 |
| 234 addPart(true, part1); | 299 return buffer.toString(); |
| 235 addPart(?part2, part2); | 300 } |
| 236 addPart(?part3, part3); | |
| 237 addPart(?part4, part4); | |
| 238 addPart(?part5, part5); | |
| 239 addPart(?part6, part6); | |
| 240 addPart(?part7, part7); | |
| 241 addPart(?part8, part8); | |
| 242 | 301 |
| 243 return buffer.toString(); | 302 // TODO(nweiz): add a UNC example for Windows once issue 7323 is fixed. |
| 303 /// 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.
| |
| 304 /// Example: | |
| 305 /// | |
| 306 /// builder.split('path/to/foo'); // -> ['path', 'to', 'foo'] | |
| 307 /// | |
| 308 /// If [path] is absolute, the root directory will be the first element in the | |
| 309 /// array. Example: | |
| 310 /// | |
| 311 /// // Unix | |
| 312 /// builder.split('/path/to/foo'); // -> ['/', 'path', 'to', 'foo'] | |
| 313 /// | |
| 314 /// // Windows | |
| 315 /// builder.split(r'C:\path\to\foo'); // -> [r'C:\', 'path', 'to', 'foo'] | |
| 316 List<String> split(String path) { | |
| 317 var parsed = _parse(path); | |
| 318 // Filter out empty parts that exist due to multiple separators in a row. | |
| 319 parsed.parts = parsed.parts.filter((part) => part != ''); | |
| 320 if (parsed.root != null) parsed.parts.insertRange(0, 1, parsed.root); | |
| 321 return parsed.parts; | |
| 244 } | 322 } |
| 245 | 323 |
| 246 /// Normalizes [path], simplifying it by handling `..`, and `.`, and | 324 /// Normalizes [path], simplifying it by handling `..`, and `.`, and |
| 247 /// removing redundant path separators whenever possible. | 325 /// removing redundant path separators whenever possible. |
| 248 /// | 326 /// |
| 249 /// builder.normalize('path/./to/..//file.text'); // -> 'path/file.txt' | 327 /// builder.normalize('path/./to/..//file.text'); // -> 'path/file.txt' |
| 250 String normalize(String path) { | 328 String normalize(String path) { |
| 251 if (path == '') return path; | 329 if (path == '') return path; |
| 252 | 330 |
| 253 var parsed = _parse(path); | 331 var parsed = _parse(path); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 271 return join(root, part1, part2, part3, part4, part5, part6, part7); | 349 return join(root, part1, part2, part3, part4, part5, part6, part7); |
| 272 } | 350 } |
| 273 | 351 |
| 274 /// Attempts to convert [path] to an equivalent relative path relative to | 352 /// Attempts to convert [path] to an equivalent relative path relative to |
| 275 /// [root]. | 353 /// [root]. |
| 276 /// | 354 /// |
| 277 /// var builder = new Builder(root: '/root/path'); | 355 /// var builder = new Builder(root: '/root/path'); |
| 278 /// builder.relative('/root/path/a/b.dart'); // -> 'a/b.dart' | 356 /// builder.relative('/root/path/a/b.dart'); // -> 'a/b.dart' |
| 279 /// builder.relative('/root/other.dart'); // -> '../other.dart' | 357 /// builder.relative('/root/other.dart'); // -> '../other.dart' |
| 280 /// | 358 /// |
| 359 /// If the [to] argument is passed, [path] is made relative to that instead. | |
| 360 /// | |
| 361 /// builder.relative('/root/path/a/b.dart', | |
| 362 /// to: '/root/path'); // -> 'a/b.dart' | |
| 363 /// builder.relative('/root/other.dart', | |
| 364 /// to: '/root/path'); // -> '../other.dart' | |
| 365 /// | |
| 281 /// Since there is no relative path from one drive letter to another on | 366 /// Since there is no relative path from one drive letter to another on |
| 282 /// Windows, this will return an absolute path in that case. | 367 /// Windows, this will return an absolute path in that case. |
| 283 /// | 368 /// |
| 284 /// var builder = new Builder(root: r'C:\home'); | 369 /// builder.relative(r'D:\other', to: r'C:\other'); // -> 'D:\other' |
| 285 /// builder.relative(r'D:\other'); // -> 'D:\other' | 370 String relative(String path, {String to}) { |
| 286 String relative(String path) { | |
| 287 if (path == '') return '.'; | 371 if (path == '') return '.'; |
| 288 | 372 |
| 289 // If the base path is relative, resolve it relative to the current | 373 // If the base path is relative, resolve it relative to the current |
| 290 // directory. | 374 // directory. |
| 291 var base = root; | 375 var base = to == null ? root : to; |
| 292 if (this.isRelative(base)) base = absolute(base); | 376 if (this.isRelative(base)) base = absolute(base); |
| 293 | 377 |
| 294 // If the given path is relative, resolve it relative to the base. | 378 // If the given path is relative, resolve it relative to the base. |
| 295 if (this.isRelative(path)) return this.normalize(path); | 379 if (this.isRelative(path)) return this.normalize(path); |
| 296 | 380 |
| 297 var baseParsed = _parse(base)..normalize(); | 381 var baseParsed = _parse(base)..normalize(); |
| 298 var pathParsed = _parse(path)..normalize(); | 382 var pathParsed = _parse(path)..normalize(); |
| 299 | 383 |
| 300 // If the root prefixes don't match (for example, different drive letters | 384 // If the root prefixes don't match (for example, different drive letters |
| 301 // on Windows), then there is no relative path, so just return the absolute | 385 // on Windows), then there is no relative path, so just return the absolute |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 526 | 610 |
| 527 var lastDot = file.lastIndexOf('.'); | 611 var lastDot = file.lastIndexOf('.'); |
| 528 | 612 |
| 529 // If there is no dot, or it's the first character, like '.bashrc', it | 613 // If there is no dot, or it's the first character, like '.bashrc', it |
| 530 // doesn't count. | 614 // doesn't count. |
| 531 if (lastDot <= 0) return [file, '']; | 615 if (lastDot <= 0) return [file, '']; |
| 532 | 616 |
| 533 return [file.substring(0, lastDot), file.substring(lastDot)]; | 617 return [file.substring(0, lastDot), file.substring(lastDot)]; |
| 534 } | 618 } |
| 535 } | 619 } |
| OLD | NEW |