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 /// | 6 /// |
7 /// ## Installing ## | 7 /// ## Installing ## |
8 /// | 8 /// |
9 /// Use [pub][] to install this package. Add the following to your | 9 /// Use [pub][] to install this package. Add the following to your |
10 /// `pubspec.yaml` file. | 10 /// `pubspec.yaml` file. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 _builder.basenameWithoutExtension(path); | 107 _builder.basenameWithoutExtension(path); |
108 | 108 |
109 /// Gets the part of [path] before the last separator. | 109 /// Gets the part of [path] before the last separator. |
110 /// | 110 /// |
111 /// path.dirname('path/to/foo.dart'); // -> 'path/to' | 111 /// path.dirname('path/to/foo.dart'); // -> 'path/to' |
112 /// path.dirname('path/to'); // -> 'path' | 112 /// path.dirname('path/to'); // -> 'path' |
113 /// | 113 /// |
114 /// Trailing separators are ignored. | 114 /// Trailing separators are ignored. |
115 /// | 115 /// |
116 /// builder.dirname('path/to/'); // -> 'path' | 116 /// builder.dirname('path/to/'); // -> 'path' |
117 /// | |
118 /// If an absolute path contains no directories, only a root, then the root | |
119 /// is returned. | |
120 /// | |
121 /// path.dirname('/'); // -> '/' (posix) | |
122 /// path.dirname('c:\'); // -> 'c:\' (windows) | |
123 /// | |
124 /// If a relative path has no directories, then '.' is returned. | |
125 /// | |
126 /// path.dirname('foo'); // -> '.' | |
127 /// path.dirname(''); // -> '.' | |
117 String dirname(String path) => _builder.dirname(path); | 128 String dirname(String path) => _builder.dirname(path); |
118 | 129 |
119 /// Gets the file extension of [path]: the portion of [basename] from the last | 130 /// Gets the file extension of [path]: the portion of [basename] from the last |
120 /// `.` to the end (including the `.` itself). | 131 /// `.` to the end (including the `.` itself). |
121 /// | 132 /// |
122 /// path.extension('path/to/foo.dart'); // -> '.dart' | 133 /// path.extension('path/to/foo.dart'); // -> '.dart' |
123 /// path.extension('path/to/foo'); // -> '' | 134 /// path.extension('path/to/foo'); // -> '' |
124 /// path.extension('path.to/foo'); // -> '' | 135 /// path.extension('path.to/foo'); // -> '' |
125 /// path.extension('path/to/foo.dart.js'); // -> '.js' | 136 /// path.extension('path/to/foo.dart.js'); // -> '.js' |
126 /// | 137 /// |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 .toList(); | 592 .toList(); |
582 if (parsed.root != null) parsed.parts.insert(0, parsed.root); | 593 if (parsed.root != null) parsed.parts.insert(0, parsed.root); |
583 return parsed.parts; | 594 return parsed.parts; |
584 } | 595 } |
585 | 596 |
586 /// Normalizes [path], simplifying it by handling `..`, and `.`, and | 597 /// Normalizes [path], simplifying it by handling `..`, and `.`, and |
587 /// removing redundant path separators whenever possible. | 598 /// removing redundant path separators whenever possible. |
588 /// | 599 /// |
589 /// builder.normalize('path/./to/..//file.text'); // -> 'path/file.txt' | 600 /// builder.normalize('path/./to/..//file.text'); // -> 'path/file.txt' |
590 String normalize(String path) { | 601 String normalize(String path) { |
591 if (path == '') return path; | |
592 | |
593 var parsed = _parse(path); | 602 var parsed = _parse(path); |
594 parsed.normalize(); | 603 parsed.normalize(); |
595 return parsed.toString(); | 604 return parsed.toString(); |
596 } | 605 } |
597 | 606 |
598 /// Creates a new path by appending the given path parts to the [root]. | 607 /// Creates a new path by appending the given path parts to the [root]. |
599 /// Equivalent to [join()] with [root] as the first argument. Example: | 608 /// Equivalent to [join()] with [root] as the first argument. Example: |
600 /// | 609 /// |
601 /// var builder = new Builder(root: 'root'); | 610 /// var builder = new Builder(root: 'root'); |
602 /// builder.resolve('path', 'to', 'foo'); // -> 'root/path/to/foo' | 611 /// builder.resolve('path', 'to', 'foo'); // -> 'root/path/to/foo' |
(...skipping 20 matching lines...) Expand all Loading... | |
623 /// Windows, this will return an absolute path in that case. | 632 /// Windows, this will return an absolute path in that case. |
624 /// | 633 /// |
625 /// builder.relative(r'D:\other', from: r'C:\other'); // -> 'D:\other' | 634 /// builder.relative(r'D:\other', from: r'C:\other'); // -> 'D:\other' |
626 /// | 635 /// |
627 /// This will also return an absolute path if an absolute [path] is passed to | 636 /// This will also return an absolute path if an absolute [path] is passed to |
628 /// a builder with a relative [root]. | 637 /// a builder with a relative [root]. |
629 /// | 638 /// |
630 /// var builder = new Builder(r'some/relative/path'); | 639 /// var builder = new Builder(r'some/relative/path'); |
631 /// builder.relative(r'/absolute/path'); // -> '/absolute/path' | 640 /// builder.relative(r'/absolute/path'); // -> '/absolute/path' |
632 String relative(String path, {String from}) { | 641 String relative(String path, {String from}) { |
633 if (path == '') return '.'; | |
634 | |
635 from = from == null ? root : this.join(root, from); | 642 from = from == null ? root : this.join(root, from); |
636 | 643 |
637 // We can't determine the path from a relative path to an absolute path. | 644 // We can't determine the path from a relative path to an absolute path. |
638 if (this.isRelative(from) && this.isAbsolute(path)) { | 645 if (this.isRelative(from) && this.isAbsolute(path)) { |
639 return this.normalize(path); | 646 return this.normalize(path); |
640 } | 647 } |
641 | 648 |
642 // If the given path is relative, resolve it relative to the root of the | 649 // If the given path is relative, resolve it relative to the root of the |
643 // builder. | 650 // builder. |
644 if (this.isRelative(path) || this.isRootRelative(path)) { | 651 if (this.isRelative(path) || this.isRootRelative(path)) { |
(...skipping 26 matching lines...) Expand all Loading... | |
671 | 678 |
672 // Strip off their common prefix. | 679 // Strip off their common prefix. |
673 while (fromParsed.parts.length > 0 && pathParsed.parts.length > 0 && | 680 while (fromParsed.parts.length > 0 && pathParsed.parts.length > 0 && |
674 fromParsed.parts[0] == pathParsed.parts[0]) { | 681 fromParsed.parts[0] == pathParsed.parts[0]) { |
675 fromParsed.parts.removeAt(0); | 682 fromParsed.parts.removeAt(0); |
676 fromParsed.separators.removeAt(1); | 683 fromParsed.separators.removeAt(1); |
677 pathParsed.parts.removeAt(0); | 684 pathParsed.parts.removeAt(0); |
678 pathParsed.separators.removeAt(1); | 685 pathParsed.separators.removeAt(1); |
679 } | 686 } |
680 | 687 |
681 // If there are any directories left in the root path, we need to walk up | 688 // If there are any directories left in the from path, we need to walk up |
682 // out of them. | 689 // out of them. If a directory left in the from path is '..', it cannot |
nweiz
2013/07/22 21:00:33
Nit: single space after "."
Bill Hesse
2013/07/23 16:07:00
Done.
| |
690 // be cancelled by adding a '..'. | |
691 if (fromParsed.parts.length > 0 && fromParsed.parts[0] == '..') { | |
692 throw new ArgumentError('Unable to find a path to "$path" from "$from".'); | |
693 } | |
683 _growListFront(pathParsed.parts, fromParsed.parts.length, '..'); | 694 _growListFront(pathParsed.parts, fromParsed.parts.length, '..'); |
684 pathParsed.separators[0] = ''; | 695 pathParsed.separators[0] = ''; |
685 pathParsed.separators.insertAll(1, | 696 pathParsed.separators.insertAll(1, |
686 new List.filled(fromParsed.parts.length, style.separator)); | 697 new List.filled(fromParsed.parts.length, style.separator)); |
687 | 698 |
688 // Corner case: the paths completely collapsed. | 699 // Corner case: the paths completely collapsed. |
689 if (pathParsed.parts.length == 0) return '.'; | 700 if (pathParsed.parts.length == 0) return '.'; |
690 | 701 |
702 // Corner case: path was '.' and some '..' directories were added in front. | |
703 // Don't add a final '/.' in that case. | |
704 if (pathParsed.parts.length > 1 && pathParsed.parts.last == '.') { | |
705 pathParsed.parts.removeLast(); | |
706 pathParsed.separators..removeLast()..removeLast()..add(''); | |
707 } | |
708 | |
691 // Make it relative. | 709 // Make it relative. |
692 pathParsed.root = ''; | 710 pathParsed.root = ''; |
693 pathParsed.removeTrailingSeparators(); | 711 pathParsed.removeTrailingSeparators(); |
694 | 712 |
695 return pathParsed.toString(); | 713 return pathParsed.toString(); |
696 } | 714 } |
697 | 715 |
698 /// Removes a trailing extension from the last part of [path]. | 716 /// Removes a trailing extension from the last part of [path]. |
699 /// | 717 /// |
700 /// builder.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' | 718 /// builder.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1039 return copy.parts.last; | 1057 return copy.parts.last; |
1040 } | 1058 } |
1041 | 1059 |
1042 String get basenameWithoutExtension { | 1060 String get basenameWithoutExtension { |
1043 var copy = this.clone(); | 1061 var copy = this.clone(); |
1044 copy.removeTrailingSeparators(); | 1062 copy.removeTrailingSeparators(); |
1045 if (copy.parts.isEmpty) return root == null ? '' : root; | 1063 if (copy.parts.isEmpty) return root == null ? '' : root; |
1046 return copy._splitExtension()[0]; | 1064 return copy._splitExtension()[0]; |
1047 } | 1065 } |
1048 | 1066 |
1049 bool get hasTrailingSeparator => !parts.isEmpty && (parts.last == '' || separa tors.last != ''); | 1067 bool get hasTrailingSeparator => |
1068 !parts.isEmpty && (parts.last == '' || separators.last != ''); | |
1050 | 1069 |
1051 void removeTrailingSeparators() { | 1070 void removeTrailingSeparators() { |
1052 while (!parts.isEmpty && parts.last == '') { | 1071 while (!parts.isEmpty && parts.last == '') { |
1053 parts.removeLast(); | 1072 parts.removeLast(); |
1054 separators.removeLast(); | 1073 separators.removeLast(); |
1055 } | 1074 } |
1056 if (separators.length > 0) separators[separators.length - 1] = ''; | 1075 if (separators.length > 0) separators[separators.length - 1] = ''; |
1057 } | 1076 } |
1058 | 1077 |
1059 void normalize() { | 1078 void normalize() { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1131 // doesn't count. | 1150 // doesn't count. |
1132 if (lastDot <= 0) return [file, '']; | 1151 if (lastDot <= 0) return [file, '']; |
1133 | 1152 |
1134 return [file.substring(0, lastDot), file.substring(lastDot)]; | 1153 return [file.substring(0, lastDot), file.substring(lastDot)]; |
1135 } | 1154 } |
1136 | 1155 |
1137 _ParsedPath clone() => new _ParsedPath( | 1156 _ParsedPath clone() => new _ParsedPath( |
1138 style, root, isRootRelative, | 1157 style, root, isRootRelative, |
1139 new List.from(parts), new List.from(separators)); | 1158 new List.from(parts), new List.from(separators)); |
1140 } | 1159 } |
OLD | NEW |