Index: utils/pub/io.dart |
diff --git a/utils/pub/io.dart b/utils/pub/io.dart |
index 39a854d846bd0e9181c552b00fa1ecff227a9a5a..3a51555ad1c187dada4b0fb6160c4f15e22c1941 100644 |
--- a/utils/pub/io.dart |
+++ b/utils/pub/io.dart |
@@ -245,20 +245,31 @@ Future<Directory> deleteDir(dir) { |
dir.delete(recursive: true))); |
} |
-/** |
- * Asynchronously lists the contents of [dir], which can be a [String] directory |
- * path or a [Directory]. If [recursive] is `true`, lists subdirectory contents |
- * (defaults to `false`). If [includeHiddenFiles] is `true`, includes files and |
- * directories beginning with `.` (defaults to `false`). |
- */ |
+/// Asynchronously lists the contents of [dir], which can be a [String] |
+/// directory path or a [Directory]. If [recursive] is `true`, lists |
+/// subdirectory contents (defaults to `false`). If [includeHiddenFiles] is |
+/// `true`, includes files and directories beginning with `.` (defaults to |
+/// `false`). |
+/// |
+/// If [dir] is a string, the returned paths are guaranteed to begin with it. |
Future<List<String>> listDir(dir, |
- {bool recursive: false, bool includeHiddenFiles: false}) { |
+ {bool recursive: false, bool includeHiddenFiles: false, |
+ Set<String> _listedDirectories}) { |
Bob Nystrom
2012/12/17 23:42:33
Instead of making this an optional parameter, how
nweiz
2012/12/18 18:38:43
Done.
|
final completer = new Completer<List<String>>(); |
final contents = <String>[]; |
+ // Avoid recursive symlinks. |
+ if (_listedDirectories == null) _listedDirectories = new Set<String>(); |
+ var resolvedPath = new File(dir).fullPathSync(); |
+ if (_listedDirectories.contains(resolvedPath)) { |
+ return new Future.immediate([]); |
+ } |
+ _listedDirectories = new Set<String>.from(_listedDirectories); |
+ _listedDirectories.add(resolvedPath); |
+ |
dir = _getDirectory(dir); |
log.io("Listing directory ${dir.path}."); |
- var lister = dir.list(recursive: recursive); |
+ var lister = dir.list(); |
lister.onDone = (done) { |
// TODO(rnystrom): May need to sort here if it turns out onDir and onFile |
@@ -278,17 +289,32 @@ Future<List<String>> listDir(dir, |
stackTrace = localStackTrace; |
} |
+ var children = []; |
lister.onError = (error) => completer.completeException(error, stackTrace); |
lister.onDir = (file) { |
if (!includeHiddenFiles && basename(file).startsWith('.')) return; |
+ file = join(dir, basename(file)); |
contents.add(file); |
+ |
+ // TODO(nweiz): don't manually recurse once issue 7358 is fixed. |
+ if (recursive) { |
+ children.add(listDir(file, |
+ recursive: true, |
+ includeHiddenFiles: includeHiddenFiles, |
+ _listedDirectories: _listedDirectories)); |
+ } |
}; |
lister.onFile = (file) { |
if (!includeHiddenFiles && basename(file).startsWith('.')) return; |
- contents.add(file); |
+ contents.add(join(dir, basename(file))); |
}; |
- return completer.future; |
+ return completer.future.chain((contents) { |
+ return Futures.wait(children).transform((childContents) { |
+ contents.addAll(flatten(childContents)); |
+ return contents; |
+ }); |
+ }); |
} |
/** |