OLD | NEW |
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 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 if (basename(utilDir) == '') throw 'Could not find path to pub.'; | 439 if (basename(utilDir) == '') throw 'Could not find path to pub.'; |
440 utilDir = dirname(utilDir); | 440 utilDir = dirname(utilDir); |
441 } | 441 } |
442 | 442 |
443 return path.normalize(join(utilDir, 'pub', target)); | 443 return path.normalize(join(utilDir, 'pub', target)); |
444 } | 444 } |
445 | 445 |
446 /// A StringInputStream reading from stdin. | 446 /// A StringInputStream reading from stdin. |
447 final _stringStdin = new StringInputStream(stdin); | 447 final _stringStdin = new StringInputStream(stdin); |
448 | 448 |
| 449 /// Displays a message and reads a yes/no confirmation from the user. Returns |
| 450 /// a [Future] that completes to `true` if the user confirms or `false` if they |
| 451 /// do not. |
| 452 /// |
| 453 /// This will automatically append " (y/n)?" to the message, so [message] |
| 454 /// should just be a fragment like, "Are you sure you want to proceed". |
| 455 Future<bool> confirm(String message) { |
| 456 log.fine('Showing confirm message: $message'); |
| 457 stdout.writeString("$message (y/n)? "); |
| 458 return readLine().transform((line) => new RegExp(r"^[yY]").hasMatch(line)); |
| 459 } |
| 460 |
449 /// Returns a single line read from a [StringInputStream]. By default, reads | 461 /// Returns a single line read from a [StringInputStream]. By default, reads |
450 /// from stdin. | 462 /// from stdin. |
451 /// | 463 /// |
452 /// A [StringInputStream] passed to this should have no callbacks registered. | 464 /// A [StringInputStream] passed to this should have no callbacks registered. |
453 Future<String> readLine([StringInputStream stream]) { | 465 Future<String> readLine([StringInputStream stream]) { |
454 if (stream == null) stream = _stringStdin; | 466 if (stream == null) stream = _stringStdin; |
455 if (stream.closed) return new Future.immediate(''); | 467 if (stream.closed) return new Future.immediate(''); |
456 void removeCallbacks() { | 468 void removeCallbacks() { |
457 stream.onClosed = null; | 469 stream.onClosed = null; |
458 stream.onLine = null; | 470 stream.onLine = null; |
459 stream.onError = null; | 471 stream.onError = null; |
460 } | 472 } |
461 | 473 |
462 // TODO(nweiz): remove this when issue 4061 is fixed. | 474 // TODO(nweiz): remove this when issue 4061 is fixed. |
463 var stackTrace; | 475 var stackTrace; |
464 try { | 476 try { |
465 throw ""; | 477 throw ""; |
466 } catch (_, localStackTrace) { | 478 } catch (_, localStackTrace) { |
467 stackTrace = localStackTrace; | 479 stackTrace = localStackTrace; |
468 } | 480 } |
469 | 481 |
470 var completer = new Completer(); | 482 var completer = new Completer(); |
471 stream.onClosed = () { | 483 stream.onClosed = () { |
472 removeCallbacks(); | 484 removeCallbacks(); |
473 completer.complete(''); | 485 completer.complete(''); |
474 }; | 486 }; |
475 | 487 |
476 stream.onLine = () { | 488 stream.onLine = () { |
477 removeCallbacks(); | 489 removeCallbacks(); |
478 completer.complete(stream.readLine()); | 490 var line = stream.readLine(); |
| 491 log.io('Read line: $line'); |
| 492 completer.complete(line); |
479 }; | 493 }; |
480 | 494 |
481 stream.onError = (e) { | 495 stream.onError = (e) { |
482 removeCallbacks(); | 496 removeCallbacks(); |
483 completer.completeException(e, stackTrace); | 497 completer.completeException(e, stackTrace); |
484 }; | 498 }; |
485 | 499 |
486 return completer.future; | 500 return completer.future; |
487 } | 501 } |
488 | 502 |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 }).transform((_) => true); | 936 }).transform((_) => true); |
923 } | 937 } |
924 | 938 |
925 /// Create a .tar.gz archive from a list of entries. Each entry can be a | 939 /// Create a .tar.gz archive from a list of entries. Each entry can be a |
926 /// [String], [Directory], or [File] object. The root of the archive is | 940 /// [String], [Directory], or [File] object. The root of the archive is |
927 /// considered to be [baseDir], which defaults to the current working directory. | 941 /// considered to be [baseDir], which defaults to the current working directory. |
928 /// Returns an [InputStream] that will emit the contents of the archive. | 942 /// Returns an [InputStream] that will emit the contents of the archive. |
929 InputStream createTarGz(List contents, {baseDir}) { | 943 InputStream createTarGz(List contents, {baseDir}) { |
930 var buffer = new StringBuffer(); | 944 var buffer = new StringBuffer(); |
931 buffer.add('Creating .tag.gz stream containing:\n'); | 945 buffer.add('Creating .tag.gz stream containing:\n'); |
932 contents.forEach(buffer.add); | 946 contents.forEach((file) => buffer.add('$file\n')); |
933 log.fine(buffer.toString()); | 947 log.fine(buffer.toString()); |
934 | 948 |
935 // TODO(nweiz): Propagate errors to the returned stream (including non-zero | 949 // TODO(nweiz): Propagate errors to the returned stream (including non-zero |
936 // exit codes). See issue 3657. | 950 // exit codes). See issue 3657. |
937 var stream = new ListInputStream(); | 951 var stream = new ListInputStream(); |
938 | 952 |
939 if (baseDir == null) baseDir = path.current; | 953 if (baseDir == null) baseDir = path.current; |
940 baseDir = getFullPath(baseDir); | 954 baseDir = getFullPath(baseDir); |
941 contents = contents.map((entry) { | 955 contents = contents.map((entry) { |
942 entry = getFullPath(entry); | 956 entry = getFullPath(entry); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1053 return new Directory(entry); | 1067 return new Directory(entry); |
1054 } | 1068 } |
1055 | 1069 |
1056 /** | 1070 /** |
1057 * Gets a [Uri] for [uri], which can either already be one, or be a [String]. | 1071 * Gets a [Uri] for [uri], which can either already be one, or be a [String]. |
1058 */ | 1072 */ |
1059 Uri _getUri(uri) { | 1073 Uri _getUri(uri) { |
1060 if (uri is Uri) return uri; | 1074 if (uri is Uri) return uri; |
1061 return new Uri.fromString(uri); | 1075 return new Uri.fromString(uri); |
1062 } | 1076 } |
OLD | NEW |