| 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 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 args = flatten(["/c", executable, args]); | 488 args = flatten(["/c", executable, args]); |
| 489 executable = "cmd"; | 489 executable = "cmd"; |
| 490 } | 490 } |
| 491 | 491 |
| 492 final options = new ProcessOptions(); | 492 final options = new ProcessOptions(); |
| 493 if (workingDir != null) { | 493 if (workingDir != null) { |
| 494 options.workingDirectory = _getDirectory(workingDir).path; | 494 options.workingDirectory = _getDirectory(workingDir).path; |
| 495 } | 495 } |
| 496 options.environment = environment; | 496 options.environment = environment; |
| 497 | 497 |
| 498 final process = Process.start(executable, args, options); | |
| 499 | |
| 500 final outStream = new StringInputStream(process.stdout); | |
| 501 final processStdout = <String>[]; | |
| 502 | |
| 503 final errStream = new StringInputStream(process.stderr); | |
| 504 final processStderr = <String>[]; | |
| 505 | |
| 506 final completer = new Completer<PubProcessResult>(); | 498 final completer = new Completer<PubProcessResult>(); |
| 507 | 499 |
| 508 checkComplete() { | 500 Process.start(executable, args, options).then((process) { |
| 509 // Wait until the process is done and its output streams are closed. | 501 final outStream = new StringInputStream(process.stdout); |
| 510 if (!pipeStdout && !outStream.closed) return; | 502 final processStdout = <String>[]; |
| 511 if (!pipeStderr && !errStream.closed) return; | |
| 512 if (exitCode == null) return; | |
| 513 | 503 |
| 514 completer.complete(new PubProcessResult( | 504 final errStream = new StringInputStream(process.stderr); |
| 515 processStdout, processStderr, exitCode)); | 505 final processStderr = <String>[]; |
| 516 } | |
| 517 | 506 |
| 518 if (pipeStdout) { | 507 checkComplete() { |
| 519 process.stdout.pipe(stdout, close: false); | 508 // Wait until the process is done and its output streams are closed. |
| 520 } else { | 509 if (!pipeStdout && !outStream.closed) return; |
| 521 outStream.onLine = () => processStdout.add(outStream.readLine()); | 510 if (!pipeStderr && !errStream.closed) return; |
| 522 outStream.onClosed = checkComplete; | 511 if (exitCode == null) return; |
| 523 outStream.onError = (error) => completer.completeException(error); | |
| 524 } | |
| 525 | 512 |
| 526 if (pipeStderr) { | 513 completer.complete(new PubProcessResult( |
| 527 process.stderr.pipe(stderr, close: false); | 514 processStdout, processStderr, exitCode)); |
| 528 } else { | 515 } |
| 529 errStream.onLine = () => processStderr.add(errStream.readLine()); | |
| 530 errStream.onClosed = checkComplete; | |
| 531 errStream.onError = (error) => completer.completeException(error); | |
| 532 } | |
| 533 | 516 |
| 534 process.onExit = (actualExitCode) { | 517 if (pipeStdout) { |
| 535 exitCode = actualExitCode; | 518 process.stdout.pipe(stdout, close: false); |
| 536 checkComplete(); | 519 } else { |
| 537 }; | 520 outStream.onLine = () => processStdout.add(outStream.readLine()); |
| 521 outStream.onClosed = checkComplete; |
| 522 outStream.onError = (error) => completer.completeException(error); |
| 523 } |
| 538 | 524 |
| 539 process.onError = (error) => completer.completeException(error); | 525 if (pipeStderr) { |
| 526 process.stderr.pipe(stderr, close: false); |
| 527 } else { |
| 528 errStream.onLine = () => processStderr.add(errStream.readLine()); |
| 529 errStream.onClosed = checkComplete; |
| 530 errStream.onError = (error) => completer.completeException(error); |
| 531 } |
| 540 | 532 |
| 533 process.onExit = (actualExitCode) { |
| 534 exitCode = actualExitCode; |
| 535 checkComplete(); |
| 536 }; |
| 537 |
| 538 process.onError = (error) => completer.completeException(error); |
| 539 }); |
| 541 return completer.future; | 540 return completer.future; |
| 542 } | 541 } |
| 543 | 542 |
| 544 /** | 543 /** |
| 545 * Wraps [input] to provide a timeout. If [input] completes before | 544 * Wraps [input] to provide a timeout. If [input] completes before |
| 546 * [milliseconds] have passed, then the return value completes in the same way. | 545 * [milliseconds] have passed, then the return value completes in the same way. |
| 547 * However, if [milliseconds] pass before [input] has completed, it completes | 546 * However, if [milliseconds] pass before [input] has completed, it completes |
| 548 * with a [TimeoutException] with [message]. | 547 * with a [TimeoutException] with [message]. |
| 549 * | 548 * |
| 550 * Note that timing out will not cancel the asynchronous operation behind | 549 * Note that timing out will not cancel the asynchronous operation behind |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 * Extracts a `.tar.gz` file from [stream] to [destination], which can be a | 632 * Extracts a `.tar.gz` file from [stream] to [destination], which can be a |
| 634 * directory or a path. Returns whether or not the extraction was successful. | 633 * directory or a path. Returns whether or not the extraction was successful. |
| 635 */ | 634 */ |
| 636 Future<bool> extractTarGz(InputStream stream, destination) { | 635 Future<bool> extractTarGz(InputStream stream, destination) { |
| 637 destination = _getPath(destination); | 636 destination = _getPath(destination); |
| 638 | 637 |
| 639 if (Platform.operatingSystem == "windows") { | 638 if (Platform.operatingSystem == "windows") { |
| 640 return _extractTarGzWindows(stream, destination); | 639 return _extractTarGzWindows(stream, destination); |
| 641 } | 640 } |
| 642 | 641 |
| 643 var process = Process.start("tar", | |
| 644 ["--extract", "--gunzip", "--directory", destination]); | |
| 645 var completer = new Completer<int>(); | 642 var completer = new Completer<int>(); |
| 643 Process.start("tar", |
| 644 ["--extract", "--gunzip", "--directory", destination]).then((process) { |
| 646 | 645 |
| 647 process.onExit = completer.complete; | 646 process.onExit = completer.complete; |
| 648 process.onError = completer.completeException; | 647 process.onError = completer.completeException; |
| 649 | |
| 650 // Wait for the process to be fully started before writing to its | |
| 651 // stdin stream. | |
| 652 process.onStart = () { | |
| 653 stream.pipe(process.stdin); | 648 stream.pipe(process.stdin); |
| 654 process.stdout.pipe(stdout, close: false); | 649 process.stdout.pipe(stdout, close: false); |
| 655 process.stderr.pipe(stderr, close: false); | 650 process.stderr.pipe(stderr, close: false); |
| 656 }; | 651 }); |
| 657 | 652 |
| 658 return completer.future.transform((exitCode) => exitCode == 0); | 653 return completer.future.transform((exitCode) => exitCode == 0); |
| 659 } | 654 } |
| 660 | 655 |
| 661 Future<bool> _extractTarGzWindows(InputStream stream, String destination) { | 656 Future<bool> _extractTarGzWindows(InputStream stream, String destination) { |
| 662 // TODO(rnystrom): In the repo's history, there is an older implementation of | 657 // TODO(rnystrom): In the repo's history, there is an older implementation of |
| 663 // this that does everything in memory by piping streams directly together | 658 // this that does everything in memory by piping streams directly together |
| 664 // instead of writing out temp files. The code is simpler, but unfortunately, | 659 // instead of writing out temp files. The code is simpler, but unfortunately, |
| 665 // 7zip seems to periodically fail when we invoke it from Dart and tell it to | 660 // 7zip seems to periodically fail when we invoke it from Dart and tell it to |
| 666 // read from stdin instead of a file. Consider resurrecting that version if | 661 // read from stdin instead of a file. Consider resurrecting that version if |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 return new Directory(entry); | 769 return new Directory(entry); |
| 775 } | 770 } |
| 776 | 771 |
| 777 /** | 772 /** |
| 778 * 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]. |
| 779 */ | 774 */ |
| 780 Uri _getUri(uri) { | 775 Uri _getUri(uri) { |
| 781 if (uri is Uri) return uri; | 776 if (uri is Uri) return uri; |
| 782 return new Uri.fromString(uri); | 777 return new Uri.fromString(uri); |
| 783 } | 778 } |
| OLD | NEW |