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

Side by Side Diff: pkg/path/lib/path.dart

Issue 19231002: Port dart:io Path tests to package:path. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 5 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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'); // -> 'to' 112 /// path.dirname('path/to'); // -> 'to'
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.
Bob Nystrom 2013/07/15 17:49:29 Blank line here.
Bill Hesse 2013/07/16 12:42:26 Done.
125 /// path.dirname('foo'); // -> '.'
126 /// path.dirname(''); // -> '.'
117 String dirname(String path) => _builder.dirname(path); 127 String dirname(String path) => _builder.dirname(path);
118 128
119 /// Gets the file extension of [path]: the portion of [basename] from the last 129 /// Gets the file extension of [path]: the portion of [basename] from the last
120 /// `.` to the end (including the `.` itself). 130 /// `.` to the end (including the `.` itself).
121 /// 131 ///
122 /// path.extension('path/to/foo.dart'); // -> '.dart' 132 /// path.extension('path/to/foo.dart'); // -> '.dart'
123 /// path.extension('path/to/foo'); // -> '' 133 /// path.extension('path/to/foo'); // -> ''
124 /// path.extension('path.to/foo'); // -> '' 134 /// path.extension('path.to/foo'); // -> ''
125 /// path.extension('path/to/foo.dart.js'); // -> '.js' 135 /// path.extension('path/to/foo.dart.js'); // -> '.js'
126 /// 136 ///
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 .toList(); 591 .toList();
582 if (parsed.root != null) parsed.parts.insert(0, parsed.root); 592 if (parsed.root != null) parsed.parts.insert(0, parsed.root);
583 return parsed.parts; 593 return parsed.parts;
584 } 594 }
585 595
586 /// Normalizes [path], simplifying it by handling `..`, and `.`, and 596 /// Normalizes [path], simplifying it by handling `..`, and `.`, and
587 /// removing redundant path separators whenever possible. 597 /// removing redundant path separators whenever possible.
588 /// 598 ///
589 /// builder.normalize('path/./to/..//file.text'); // -> 'path/file.txt' 599 /// builder.normalize('path/./to/..//file.text'); // -> 'path/file.txt'
590 String normalize(String path) { 600 String normalize(String path) {
591 if (path == '') return path;
592
593 var parsed = _parse(path); 601 var parsed = _parse(path);
594 parsed.normalize(); 602 parsed.normalize();
595 return parsed.toString(); 603 return parsed.toString();
596 } 604 }
597 605
598 /// Creates a new path by appending the given path parts to the [root]. 606 /// Creates a new path by appending the given path parts to the [root].
599 /// Equivalent to [join()] with [root] as the first argument. Example: 607 /// Equivalent to [join()] with [root] as the first argument. Example:
600 /// 608 ///
601 /// var builder = new Builder(root: 'root'); 609 /// var builder = new Builder(root: 'root');
602 /// builder.resolve('path', 'to', 'foo'); // -> 'root/path/to/foo' 610 /// builder.resolve('path', 'to', 'foo'); // -> 'root/path/to/foo'
(...skipping 20 matching lines...) Expand all
623 /// Windows, this will return an absolute path in that case. 631 /// Windows, this will return an absolute path in that case.
624 /// 632 ///
625 /// builder.relative(r'D:\other', from: r'C:\other'); // -> 'D:\other' 633 /// builder.relative(r'D:\other', from: r'C:\other'); // -> 'D:\other'
626 /// 634 ///
627 /// This will also return an absolute path if an absolute [path] is passed to 635 /// This will also return an absolute path if an absolute [path] is passed to
628 /// a builder with a relative [root]. 636 /// a builder with a relative [root].
629 /// 637 ///
630 /// var builder = new Builder(r'some/relative/path'); 638 /// var builder = new Builder(r'some/relative/path');
631 /// builder.relative(r'/absolute/path'); // -> '/absolute/path' 639 /// builder.relative(r'/absolute/path'); // -> '/absolute/path'
632 String relative(String path, {String from}) { 640 String relative(String path, {String from}) {
633 if (path == '') return '.';
634
Bill Hesse 2013/07/15 16:58:48 This is wrong if [from] is not null. It should wo
Bob Nystrom 2013/07/15 17:49:29 Eek, you're right.
635 from = from == null ? root : this.join(root, from); 641 from = from == null ? root : this.join(root, from);
636 642
637 // We can't determine the path from a relative path to an absolute path. 643 // We can't determine the path from a relative path to an absolute path.
638 if (this.isRelative(from) && this.isAbsolute(path)) { 644 if (this.isRelative(from) && this.isAbsolute(path)) {
639 return this.normalize(path); 645 return this.normalize(path);
640 } 646 }
641 647
642 // If the given path is relative, resolve it relative to the root of the 648 // If the given path is relative, resolve it relative to the root of the
643 // builder. 649 // builder.
644 if (this.isRelative(path) || this.isRootRelative(path)) { 650 if (this.isRelative(path) || this.isRootRelative(path)) {
(...skipping 26 matching lines...) Expand all
671 677
672 // Strip off their common prefix. 678 // Strip off their common prefix.
673 while (fromParsed.parts.length > 0 && pathParsed.parts.length > 0 && 679 while (fromParsed.parts.length > 0 && pathParsed.parts.length > 0 &&
674 fromParsed.parts[0] == pathParsed.parts[0]) { 680 fromParsed.parts[0] == pathParsed.parts[0]) {
675 fromParsed.parts.removeAt(0); 681 fromParsed.parts.removeAt(0);
676 fromParsed.separators.removeAt(1); 682 fromParsed.separators.removeAt(1);
677 pathParsed.parts.removeAt(0); 683 pathParsed.parts.removeAt(0);
678 pathParsed.separators.removeAt(1); 684 pathParsed.separators.removeAt(1);
679 } 685 }
680 686
681 // If there are any directories left in the root path, we need to walk up 687 // If there are any directories left in the from path, we need to walk up
682 // out of them. 688 // out of them. If a directory left in the from path is '..', it cannot
689 // be cancelled by adding a '..'.
690 if (fromParsed.parts.length > 0 && fromParsed.parts[0] == '..') {
691 throw new ArgumentError('Unable to find a path to "$path" from "$from".');
692 }
Bob Nystrom 2013/07/15 17:49:29 Can you give me an example where this will come in
Bill Hesse 2013/07/16 12:42:26 My tests include this case. Any case with ".." in
683 _growListFront(pathParsed.parts, fromParsed.parts.length, '..'); 693 _growListFront(pathParsed.parts, fromParsed.parts.length, '..');
684 pathParsed.separators[0] = ''; 694 pathParsed.separators[0] = '';
685 pathParsed.separators.insertAll(1, 695 pathParsed.separators.insertAll(1,
686 new List.filled(fromParsed.parts.length, style.separator)); 696 new List.filled(fromParsed.parts.length, style.separator));
687 697
688 // Corner case: the paths completely collapsed. 698 // Corner case: the paths completely collapsed.
689 if (pathParsed.parts.length == 0) return '.'; 699 if (pathParsed.parts.length == 0) return '.';
690 700
701 // Corner case: path was '.' and some '..' directories were added in front.
702 // Don't add a final '/.' in that case.
703 if (pathParsed.parts.length > 1 && pathParsed.parts.last == '.') {
704 pathParsed.parts.removeLast();
705 pathParsed.separators..removeLast()..removeLast()..add('');
706 }
Bob Nystrom 2013/07/15 17:49:29 Nice catch. Add a test for this?
Bill Hesse 2013/07/16 12:42:26 There is a test for this, in my tests.
707
691 // Make it relative. 708 // Make it relative.
692 pathParsed.root = ''; 709 pathParsed.root = '';
693 pathParsed.removeTrailingSeparators(); 710 pathParsed.removeTrailingSeparators();
694 711
695 return pathParsed.toString(); 712 return pathParsed.toString();
696 } 713 }
697 714
698 /// Removes a trailing extension from the last part of [path]. 715 /// Removes a trailing extension from the last part of [path].
699 /// 716 ///
700 /// builder.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' 717 /// builder.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 return copy.parts.last; 1056 return copy.parts.last;
1040 } 1057 }
1041 1058
1042 String get basenameWithoutExtension { 1059 String get basenameWithoutExtension {
1043 var copy = this.clone(); 1060 var copy = this.clone();
1044 copy.removeTrailingSeparators(); 1061 copy.removeTrailingSeparators();
1045 if (copy.parts.isEmpty) return root == null ? '' : root; 1062 if (copy.parts.isEmpty) return root == null ? '' : root;
1046 return copy._splitExtension()[0]; 1063 return copy._splitExtension()[0];
1047 } 1064 }
1048 1065
1049 bool get hasTrailingSeparator => !parts.isEmpty && (parts.last == '' || separa tors.last != ''); 1066 bool get hasTrailingSeparator =>
1067 !parts.isEmpty && (parts.last == '' || separators.last != '');
1050 1068
1051 void removeTrailingSeparators() { 1069 void removeTrailingSeparators() {
1052 while (!parts.isEmpty && parts.last == '') { 1070 while (!parts.isEmpty && parts.last == '') {
1053 parts.removeLast(); 1071 parts.removeLast();
1054 separators.removeLast(); 1072 separators.removeLast();
1055 } 1073 }
1056 if (separators.length > 0) separators[separators.length - 1] = ''; 1074 if (separators.length > 0) separators[separators.length - 1] = '';
1057 } 1075 }
1058 1076
1059 void normalize() { 1077 void normalize() {
(...skipping 30 matching lines...) Expand all
1090 var newSeparators = new List.generate( 1108 var newSeparators = new List.generate(
1091 newParts.length, (_) => style.separator, growable: true); 1109 newParts.length, (_) => style.separator, growable: true);
1092 newSeparators.insert(0, 1110 newSeparators.insert(0,
1093 isAbsolute && newParts.length > 0 && 1111 isAbsolute && newParts.length > 0 &&
1094 root.contains(style.needsSeparatorPattern) ? 1112 root.contains(style.needsSeparatorPattern) ?
1095 style.separator : ''); 1113 style.separator : '');
1096 1114
1097 parts = newParts; 1115 parts = newParts;
1098 separators = newSeparators; 1116 separators = newSeparators;
1099 1117
1100 // Normalize the Windows root if needed. 1118 // Normalize the Windows root if needed.
Bill Hesse 2013/07/15 16:58:48 oops.
1101 if (root != null && style == Style.windows) { 1119 if (root != null && style == Style.windows) {
1102 root = root.replaceAll('/', '\\'); 1120 root = root.replaceAll('/', '\\');
1103 } 1121 }
1104 removeTrailingSeparators(); 1122 removeTrailingSeparators();
1105 } 1123 }
1106 1124
1107 String toString() { 1125 String toString() {
1108 var builder = new StringBuffer(); 1126 var builder = new StringBuffer();
1109 if (root != null) builder.write(root); 1127 if (root != null) builder.write(root);
1110 for (var i = 0; i < parts.length; i++) { 1128 for (var i = 0; i < parts.length; i++) {
(...skipping 20 matching lines...) Expand all
1131 // doesn't count. 1149 // doesn't count.
1132 if (lastDot <= 0) return [file, '']; 1150 if (lastDot <= 0) return [file, ''];
1133 1151
1134 return [file.substring(0, lastDot), file.substring(lastDot)]; 1152 return [file.substring(0, lastDot), file.substring(lastDot)];
1135 } 1153 }
1136 1154
1137 _ParsedPath clone() => new _ParsedPath( 1155 _ParsedPath clone() => new _ParsedPath(
1138 style, root, isRootRelative, 1156 style, root, isRootRelative,
1139 new List.from(parts), new List.from(separators)); 1157 new List.from(parts), new List.from(separators));
1140 } 1158 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698