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

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

Issue 12879015: Provisionally stop working around issues 9252 and 9253. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes. Created 7 years, 9 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
« no previous file with comments | « utils/pub/hosted_source.dart ('k') | utils/pub/source.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 /// Helper functionality to make working with IO easier. 5 /// Helper functionality to make working with IO easier.
6 library io; 6 library io;
7 7
8 import 'dart:async'; 8 import 'dart:async';
9 import 'dart:io'; 9 import 'dart:io';
10 import 'dart:isolate'; 10 import 'dart:isolate';
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 /// Creates a temp directory whose name will be based on [dir] with a unique 121 /// Creates a temp directory whose name will be based on [dir] with a unique
122 /// suffix appended to it. If [dir] is not provided, a temp directory will be 122 /// suffix appended to it. If [dir] is not provided, a temp directory will be
123 /// created in a platform-dependent temporary location. Returns the path of the 123 /// created in a platform-dependent temporary location. Returns the path of the
124 /// created directory. 124 /// created directory.
125 String createTempDir([dir = '']) { 125 String createTempDir([dir = '']) {
126 var tempDir = new Directory(dir).createTempSync(); 126 var tempDir = new Directory(dir).createTempSync();
127 log.io("Created temp directory ${tempDir.path}"); 127 log.io("Created temp directory ${tempDir.path}");
128 return tempDir.path; 128 return tempDir.path;
129 } 129 }
130 130
131 // TODO(nweiz): Remove this when issue 9252 is fixed. 131 /// Recursively deletes [dir].
132 /// Asynchronously recursively deletes [dir]. Returns a [Future] that completes 132 void deleteDir(String dir) {
133 /// when the deletion is done. 133 log.io("Deleting directory $dir.");
134 Future<String> deleteDir(String dir) { 134 new Directory(dir).deleteSync(recursive: true);
135 return _attemptRetryable(() => log.ioAsync("delete directory $dir",
136 new Directory(dir).delete(recursive: true).then((_) => dir)));
137 } 135 }
138 136
139 /// Asynchronously lists the contents of [dir]. If [recursive] is `true`, lists 137 /// Asynchronously lists the contents of [dir]. If [recursive] is `true`, lists
140 /// subdirectory contents (defaults to `false`). If [includeHiddenFiles] is 138 /// subdirectory contents (defaults to `false`). If [includeHiddenFiles] is
141 /// `true`, includes files and directories beginning with `.` (defaults to 139 /// `true`, includes files and directories beginning with `.` (defaults to
142 /// `false`). 140 /// `false`).
143 /// 141 ///
144 /// If [dir] is a string, the returned paths are guaranteed to begin with it. 142 /// If [dir] is a string, the returned paths are guaranteed to begin with it.
145 Future<List<String>> listDir(String dir, 143 Future<List<String>> listDir(String dir,
146 {bool recursive: false, bool includeHiddenFiles: false}) { 144 {bool recursive: false, bool includeHiddenFiles: false}) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 }); 199 });
202 } 200 }
203 201
204 return doList(dir, new Set<String>()); 202 return doList(dir, new Set<String>());
205 } 203 }
206 204
207 /// Determines if [dir] exists on the file system. 205 /// Determines if [dir] exists on the file system.
208 bool dirExists(String dir) => new Directory(dir).existsSync(); 206 bool dirExists(String dir) => new Directory(dir).existsSync();
209 207
210 /// "Cleans" [dir]. If that directory already exists, it will be deleted. Then a 208 /// "Cleans" [dir]. If that directory already exists, it will be deleted. Then a
211 /// new empty directory will be created. Returns a [Future] that completes when 209 /// new empty directory will be created.
212 /// the new clean directory is created. 210 void cleanDir(String dir) {
213 Future<String> cleanDir(String dir) { 211 if (dirExists(dir)) {
214 return defer(() { 212 // Delete it first.
215 if (dirExists(dir)) { 213 deleteDir(dir);
216 // Delete it first. 214 } else if (fileExists(dir)) {
217 return deleteDir(dir).then((_) => createDir(dir)); 215 // If there is a non-directory there (file or symlink), delete it.
218 } 216 deleteFile(dir);
217 }
219 218
220 if (fileExists(dir)) { 219 // Just create it.
221 // If there is a non-directory there (file or symlink), delete it. 220 createDir(dir);
222 deleteFile(dir);
223 return createDir(dir);
224 }
225
226 // Just create it.
227 return createDir(dir);
228 });
229 } 221 }
230 222
231 // TODO(nweiz): remove this when issue 9253 is fixed. 223 /// Renames (i.e. moves) the directory [from] to [to].
232 /// Renames (i.e. moves) the directory [from] to [to]. Returns a [Future] with 224 void renameDir(String from, String to) {
233 /// the destination directory.
234 Future<String> renameDir(String from, String to) {
235 log.io("Renaming directory $from to $to."); 225 log.io("Renaming directory $from to $to.");
236 226 new Directory(from).renameSync(to);
237 return _attemptRetryable(() => new Directory(from).rename(to)).then((dir) {
238 log.fine("Renamed directory $from to $to.");
239 return to;
240 });
241 }
242
243 /// On Windows, we sometimes get failures where the directory is still in use
244 /// when we try to do something with it. This is usually because the OS hasn't
245 /// noticed yet that a process using that directory has closed. To be a bit
246 /// more resilient, we wait and retry a few times.
247 ///
248 /// Takes a [callback] which returns a future for the operation being attempted.
249 /// If that future completes with an error, it will slepp and then [callback]
250 /// will be invoked again to retry the operation. It will try a few times before
251 /// giving up.
252 Future _attemptRetryable(Future callback()) {
253 // Only do lame retry logic on Windows.
254 if (Platform.operatingSystem != 'windows') return callback();
255
256 var attempts = 0;
257 makeAttempt(_) {
258 attempts++;
259 return callback().catchError((e) {
260 if (attempts >= 10) {
261 throw 'Could not complete operation. Gave up after $attempts attempts.';
262 }
263
264 // Wait a bit and try again.
265 log.fine("Operation failed, retrying (attempt $attempts).");
266 return sleep(500).then(makeAttempt);
267 });
268 }
269
270 return makeAttempt(null);
271 } 227 }
272 228
273 /// Creates a new symlink at path [symlink] that points to [target]. Returns a 229 /// Creates a new symlink at path [symlink] that points to [target]. Returns a
274 /// [Future] which completes to the path to the symlink file. 230 /// [Future] which completes to the path to the symlink file.
275 /// 231 ///
276 /// If [relative] is true, creates a symlink with a relative path from the 232 /// If [relative] is true, creates a symlink with a relative path from the
277 /// symlink to the target. Otherwise, uses the [target] path unmodified. 233 /// symlink to the target. Otherwise, uses the [target] path unmodified.
278 /// 234 ///
279 /// Note that on Windows, only directories may be symlinked to. 235 /// Note that on Windows, only directories may be symlinked to.
280 Future<String> createSymlink(String target, String symlink, 236 Future<String> createSymlink(String target, String symlink,
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 }).catchError((e) { 569 }).catchError((e) {
614 if (completer.isCompleted) return; 570 if (completer.isCompleted) return;
615 timer.cancel(); 571 timer.cancel();
616 completer.completeError(e); 572 completer.completeError(e);
617 }); 573 });
618 return completer.future; 574 return completer.future;
619 } 575 }
620 576
621 /// Creates a temporary directory and passes its path to [fn]. Once the [Future] 577 /// Creates a temporary directory and passes its path to [fn]. Once the [Future]
622 /// returned by [fn] completes, the temporary directory and all its contents 578 /// returned by [fn] completes, the temporary directory and all its contents
623 /// will be deleted. 579 /// will be deleted. [fn] can also return `null`, in which case the temporary
580 /// directory is deleted immediately afterwards.
624 /// 581 ///
625 /// Returns a future that completes to the value that the future returned from 582 /// Returns a future that completes to the value that the future returned from
626 /// [fn] completes to. 583 /// [fn] completes to.
627 Future withTempDir(Future fn(String path)) { 584 Future withTempDir(Future fn(String path)) {
628 return defer(() { 585 return defer(() {
629 var tempDir = createTempDir(); 586 var tempDir = createTempDir();
630 return fn(tempDir).whenComplete(() { 587 return new Future.of(() => fn(tempDir))
631 return deleteDir(tempDir); 588 .whenComplete(() => deleteDir(tempDir));
632 });
633 }); 589 });
634 } 590 }
635 591
636 /// Extracts a `.tar.gz` file from [stream] to [destination]. Returns whether 592 /// Extracts a `.tar.gz` file from [stream] to [destination]. Returns whether
637 /// or not the extraction was successful. 593 /// or not the extraction was successful.
638 Future<bool> extractTarGz(Stream<List<int>> stream, String destination) { 594 Future<bool> extractTarGz(Stream<List<int>> stream, String destination) {
639 log.fine("Extracting .tar.gz stream to $destination."); 595 log.fine("Extracting .tar.gz stream to $destination.");
640 596
641 if (Platform.operatingSystem == "windows") { 597 if (Platform.operatingSystem == "windows") {
642 return _extractTarGzWindows(stream, destination); 598 return _extractTarGzWindows(stream, destination);
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 const PubProcessResult(this.stdout, this.stderr, this.exitCode); 768 const PubProcessResult(this.stdout, this.stderr, this.exitCode);
813 769
814 bool get success => exitCode == 0; 770 bool get success => exitCode == 0;
815 } 771 }
816 772
817 /// Gets a [Uri] for [uri], which can either already be one, or be a [String]. 773 /// Gets a [Uri] for [uri], which can either already be one, or be a [String].
818 Uri _getUri(uri) { 774 Uri _getUri(uri) {
819 if (uri is Uri) return uri; 775 if (uri is Uri) return uri;
820 return Uri.parse(uri); 776 return Uri.parse(uri);
821 } 777 }
OLDNEW
« no previous file with comments | « utils/pub/hosted_source.dart ('k') | utils/pub/source.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698