Chromium Code Reviews| 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; |
| + }); |
| + }); |
| } |
| /** |