Chromium Code Reviews

Side by Side Diff: utils/pub/io.dart

Issue 11553043: Make listDir always emit paths within the given directory. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review change + listDir tests Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
« no previous file with comments | « utils/pub/command_lish.dart ('k') | utils/pub/validator/lib.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /** 5 /**
6 * Helper functionality to make working with IO easier. 6 * Helper functionality to make working with IO easier.
7 */ 7 */
8 library io; 8 library io;
9 9
10 import 'dart:io'; 10 import 'dart:io';
(...skipping 227 matching lines...)
238 * Asynchronously recursively deletes [dir], which can be a [String] or a 238 * Asynchronously recursively deletes [dir], which can be a [String] or a
239 * [Directory]. Returns a [Future] that completes when the deletion is done. 239 * [Directory]. Returns a [Future] that completes when the deletion is done.
240 */ 240 */
241 Future<Directory> deleteDir(dir) { 241 Future<Directory> deleteDir(dir) {
242 dir = _getDirectory(dir); 242 dir = _getDirectory(dir);
243 243
244 return _attemptRetryable(() => log.ioAsync("delete directory ${dir.path}", 244 return _attemptRetryable(() => log.ioAsync("delete directory ${dir.path}",
245 dir.delete(recursive: true))); 245 dir.delete(recursive: true)));
246 } 246 }
247 247
248 /** 248 /// Asynchronously lists the contents of [dir], which can be a [String]
249 * Asynchronously lists the contents of [dir], which can be a [String] directory 249 /// directory path or a [Directory]. If [recursive] is `true`, lists
250 * path or a [Directory]. If [recursive] is `true`, lists subdirectory contents 250 /// subdirectory contents (defaults to `false`). If [includeHiddenFiles] is
251 * (defaults to `false`). If [includeHiddenFiles] is `true`, includes files and 251 /// `true`, includes files and directories beginning with `.` (defaults to
252 * directories beginning with `.` (defaults to `false`). 252 /// `false`).
253 */ 253 ///
254 /// If [dir] is a string, the returned paths are guaranteed to begin with it.
254 Future<List<String>> listDir(dir, 255 Future<List<String>> listDir(dir,
255 {bool recursive: false, bool includeHiddenFiles: false}) { 256 {bool recursive: false, bool includeHiddenFiles: false,
257 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.
256 final completer = new Completer<List<String>>(); 258 final completer = new Completer<List<String>>();
257 final contents = <String>[]; 259 final contents = <String>[];
258 260
261 // Avoid recursive symlinks.
262 if (_listedDirectories == null) _listedDirectories = new Set<String>();
263 var resolvedPath = new File(dir).fullPathSync();
264 if (_listedDirectories.contains(resolvedPath)) {
265 return new Future.immediate([]);
266 }
267 _listedDirectories = new Set<String>.from(_listedDirectories);
268 _listedDirectories.add(resolvedPath);
269
259 dir = _getDirectory(dir); 270 dir = _getDirectory(dir);
260 log.io("Listing directory ${dir.path}."); 271 log.io("Listing directory ${dir.path}.");
261 var lister = dir.list(recursive: recursive); 272 var lister = dir.list();
262 273
263 lister.onDone = (done) { 274 lister.onDone = (done) {
264 // TODO(rnystrom): May need to sort here if it turns out onDir and onFile 275 // TODO(rnystrom): May need to sort here if it turns out onDir and onFile
265 // aren't guaranteed to be called in a certain order. So far, they seem to. 276 // aren't guaranteed to be called in a certain order. So far, they seem to.
266 if (done) { 277 if (done) {
267 log.fine("Listed directory ${dir.path}:\n" 278 log.fine("Listed directory ${dir.path}:\n"
268 "${Strings.join(contents, '\n')}"); 279 "${Strings.join(contents, '\n')}");
269 completer.complete(contents); 280 completer.complete(contents);
270 } 281 }
271 }; 282 };
272 283
273 // TODO(nweiz): remove this when issue 4061 is fixed. 284 // TODO(nweiz): remove this when issue 4061 is fixed.
274 var stackTrace; 285 var stackTrace;
275 try { 286 try {
276 throw ""; 287 throw "";
277 } catch (_, localStackTrace) { 288 } catch (_, localStackTrace) {
278 stackTrace = localStackTrace; 289 stackTrace = localStackTrace;
279 } 290 }
280 291
292 var children = [];
281 lister.onError = (error) => completer.completeException(error, stackTrace); 293 lister.onError = (error) => completer.completeException(error, stackTrace);
282 lister.onDir = (file) { 294 lister.onDir = (file) {
283 if (!includeHiddenFiles && basename(file).startsWith('.')) return; 295 if (!includeHiddenFiles && basename(file).startsWith('.')) return;
296 file = join(dir, basename(file));
284 contents.add(file); 297 contents.add(file);
298
299 // TODO(nweiz): don't manually recurse once issue 7358 is fixed.
300 if (recursive) {
301 children.add(listDir(file,
302 recursive: true,
303 includeHiddenFiles: includeHiddenFiles,
304 _listedDirectories: _listedDirectories));
305 }
285 }; 306 };
286 lister.onFile = (file) { 307 lister.onFile = (file) {
287 if (!includeHiddenFiles && basename(file).startsWith('.')) return; 308 if (!includeHiddenFiles && basename(file).startsWith('.')) return;
288 contents.add(file); 309 contents.add(join(dir, basename(file)));
289 }; 310 };
290 311
291 return completer.future; 312 return completer.future.chain((contents) {
313 return Futures.wait(children).transform((childContents) {
314 contents.addAll(flatten(childContents));
315 return contents;
316 });
317 });
292 } 318 }
293 319
294 /** 320 /**
295 * Asynchronously determines if [dir], which can be a [String] directory path 321 * Asynchronously determines if [dir], which can be a [String] directory path
296 * or a [Directory], exists on the file system. Returns a [Future] that 322 * or a [Directory], exists on the file system. Returns a [Future] that
297 * completes with the result. 323 * completes with the result.
298 */ 324 */
299 Future<bool> dirExists(dir) { 325 Future<bool> dirExists(dir) {
300 dir = _getDirectory(dir); 326 dir = _getDirectory(dir);
301 return log.ioAsync("Seeing if directory ${dir.path} exists.", 327 return log.ioAsync("Seeing if directory ${dir.path} exists.",
(...skipping 765 matching lines...)
1067 return new Directory(entry); 1093 return new Directory(entry);
1068 } 1094 }
1069 1095
1070 /** 1096 /**
1071 * Gets a [Uri] for [uri], which can either already be one, or be a [String]. 1097 * Gets a [Uri] for [uri], which can either already be one, or be a [String].
1072 */ 1098 */
1073 Uri _getUri(uri) { 1099 Uri _getUri(uri) {
1074 if (uri is Uri) return uri; 1100 if (uri is Uri) return uri;
1075 return new Uri.fromString(uri); 1101 return new Uri.fromString(uri);
1076 } 1102 }
OLDNEW
« no previous file with comments | « utils/pub/command_lish.dart ('k') | utils/pub/validator/lib.dart » ('j') | no next file with comments »

Powered by Google App Engine