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 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 if (basename(utilDir) == '') throw 'Could not find path to pub.'; | 462 if (basename(utilDir) == '') throw 'Could not find path to pub.'; |
463 utilDir = dirname(utilDir); | 463 utilDir = dirname(utilDir); |
464 } | 464 } |
465 | 465 |
466 return path.normalize(join(utilDir, 'pub', target)); | 466 return path.normalize(join(utilDir, 'pub', target)); |
467 } | 467 } |
468 | 468 |
469 /// A StringInputStream reading from stdin. | 469 /// A StringInputStream reading from stdin. |
470 final _stringStdin = new StringInputStream(stdin); | 470 final _stringStdin = new StringInputStream(stdin); |
471 | 471 |
| 472 /// Displays a message and reads a yes/no confirmation from the user. Returns |
| 473 /// a [Future] that completes to `true` if the user confirms or `false` if they |
| 474 /// do not. |
| 475 /// |
| 476 /// This will automatically append " (y/n)?" to the message, so [message] |
| 477 /// should just be a fragment like, "Are you sure you want to proceed". |
| 478 Future<bool> confirm(String message) { |
| 479 log.fine('Showing confirm message: $message'); |
| 480 stdout.writeString("$message (y/n)? "); |
| 481 return readLine().transform((line) => new RegExp(r"^[yY]").hasMatch(line)); |
| 482 } |
| 483 |
472 /// Returns a single line read from a [StringInputStream]. By default, reads | 484 /// Returns a single line read from a [StringInputStream]. By default, reads |
473 /// from stdin. | 485 /// from stdin. |
474 /// | 486 /// |
475 /// A [StringInputStream] passed to this should have no callbacks registered. | 487 /// A [StringInputStream] passed to this should have no callbacks registered. |
476 Future<String> readLine([StringInputStream stream]) { | 488 Future<String> readLine([StringInputStream stream]) { |
477 if (stream == null) stream = _stringStdin; | 489 if (stream == null) stream = _stringStdin; |
478 if (stream.closed) return new Future.immediate(''); | 490 if (stream.closed) return new Future.immediate(''); |
479 void removeCallbacks() { | 491 void removeCallbacks() { |
480 stream.onClosed = null; | 492 stream.onClosed = null; |
481 stream.onLine = null; | 493 stream.onLine = null; |
482 stream.onError = null; | 494 stream.onError = null; |
483 } | 495 } |
484 | 496 |
485 // TODO(nweiz): remove this when issue 4061 is fixed. | 497 // TODO(nweiz): remove this when issue 4061 is fixed. |
486 var stackTrace; | 498 var stackTrace; |
487 try { | 499 try { |
488 throw ""; | 500 throw ""; |
489 } catch (_, localStackTrace) { | 501 } catch (_, localStackTrace) { |
490 stackTrace = localStackTrace; | 502 stackTrace = localStackTrace; |
491 } | 503 } |
492 | 504 |
493 var completer = new Completer(); | 505 var completer = new Completer(); |
494 stream.onClosed = () { | 506 stream.onClosed = () { |
495 removeCallbacks(); | 507 removeCallbacks(); |
496 completer.complete(''); | 508 completer.complete(''); |
497 }; | 509 }; |
498 | 510 |
499 stream.onLine = () { | 511 stream.onLine = () { |
500 removeCallbacks(); | 512 removeCallbacks(); |
501 completer.complete(stream.readLine()); | 513 var line = stream.readLine(); |
| 514 log.io('Read line: $line'); |
| 515 completer.complete(line); |
502 }; | 516 }; |
503 | 517 |
504 stream.onError = (e) { | 518 stream.onError = (e) { |
505 removeCallbacks(); | 519 removeCallbacks(); |
506 completer.completeException(e, stackTrace); | 520 completer.completeException(e, stackTrace); |
507 }; | 521 }; |
508 | 522 |
509 return completer.future; | 523 return completer.future; |
510 } | 524 } |
511 | 525 |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 }).transform((_) => true); | 959 }).transform((_) => true); |
946 } | 960 } |
947 | 961 |
948 /// Create a .tar.gz archive from a list of entries. Each entry can be a | 962 /// Create a .tar.gz archive from a list of entries. Each entry can be a |
949 /// [String], [Directory], or [File] object. The root of the archive is | 963 /// [String], [Directory], or [File] object. The root of the archive is |
950 /// considered to be [baseDir], which defaults to the current working directory. | 964 /// considered to be [baseDir], which defaults to the current working directory. |
951 /// Returns an [InputStream] that will emit the contents of the archive. | 965 /// Returns an [InputStream] that will emit the contents of the archive. |
952 InputStream createTarGz(List contents, {baseDir}) { | 966 InputStream createTarGz(List contents, {baseDir}) { |
953 var buffer = new StringBuffer(); | 967 var buffer = new StringBuffer(); |
954 buffer.add('Creating .tag.gz stream containing:\n'); | 968 buffer.add('Creating .tag.gz stream containing:\n'); |
955 contents.forEach(buffer.add); | 969 contents.forEach((file) => buffer.add('$file\n')); |
956 log.fine(buffer.toString()); | 970 log.fine(buffer.toString()); |
957 | 971 |
958 // TODO(nweiz): Propagate errors to the returned stream (including non-zero | 972 // TODO(nweiz): Propagate errors to the returned stream (including non-zero |
959 // exit codes). See issue 3657. | 973 // exit codes). See issue 3657. |
960 var stream = new ListInputStream(); | 974 var stream = new ListInputStream(); |
961 | 975 |
962 if (baseDir == null) baseDir = path.current; | 976 if (baseDir == null) baseDir = path.current; |
963 baseDir = getFullPath(baseDir); | 977 baseDir = getFullPath(baseDir); |
964 contents = contents.map((entry) { | 978 contents = contents.map((entry) { |
965 entry = getFullPath(entry); | 979 entry = getFullPath(entry); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 return new Directory(entry); | 1124 return new Directory(entry); |
1111 } | 1125 } |
1112 | 1126 |
1113 /** | 1127 /** |
1114 * Gets a [Uri] for [uri], which can either already be one, or be a [String]. | 1128 * Gets a [Uri] for [uri], which can either already be one, or be a [String]. |
1115 */ | 1129 */ |
1116 Uri _getUri(uri) { | 1130 Uri _getUri(uri) { |
1117 if (uri is Uri) return uri; | 1131 if (uri is Uri) return uri; |
1118 return new Uri.fromString(uri); | 1132 return new Uri.fromString(uri); |
1119 } | 1133 } |
OLD | NEW |