| 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 var processFuture = Process.start(executable, args, options); |
| 509 // Wait until the process is done and its output streams are closed. | 501 processFuture.then((process) { |
| 510 if (!pipeStdout && !outStream.closed) return; | 502 final outStream = new StringInputStream(process.stdout); |
| 511 if (!pipeStderr && !errStream.closed) return; | 503 final processStdout = <String>[]; |
| 512 if (exitCode == null) return; | |
| 513 | 504 |
| 514 completer.complete(new PubProcessResult( | 505 final errStream = new StringInputStream(process.stderr); |
| 515 processStdout, processStderr, exitCode)); | 506 final processStderr = <String>[]; |
| 516 } | |
| 517 | 507 |
| 518 if (pipeStdout) { | 508 checkComplete() { |
| 519 process.stdout.pipe(stdout, close: false); | 509 // Wait until the process is done and its output streams are closed. |
| 520 } else { | 510 if (!pipeStdout && !outStream.closed) return; |
| 521 outStream.onLine = () => processStdout.add(outStream.readLine()); | 511 if (!pipeStderr && !errStream.closed) return; |
| 522 outStream.onClosed = checkComplete; | 512 if (exitCode == null) return; |
| 523 outStream.onError = (error) => completer.completeException(error); | |
| 524 } | |
| 525 | 513 |
| 526 if (pipeStderr) { | 514 completer.complete(new PubProcessResult( |
| 527 process.stderr.pipe(stderr, close: false); | 515 processStdout, processStderr, exitCode)); |
| 528 } else { | 516 } |
| 529 errStream.onLine = () => processStderr.add(errStream.readLine()); | |
| 530 errStream.onClosed = checkComplete; | |
| 531 errStream.onError = (error) => completer.completeException(error); | |
| 532 } | |
| 533 | 517 |
| 534 process.onExit = (actualExitCode) { | 518 if (pipeStdout) { |
| 535 exitCode = actualExitCode; | 519 process.stdout.pipe(stdout, close: false); |
| 536 checkComplete(); | 520 } else { |
| 537 }; | 521 outStream.onLine = () => processStdout.add(outStream.readLine()); |
| 522 outStream.onClosed = checkComplete; |
| 523 outStream.onError = (error) => completer.completeException(error); |
| 524 } |
| 538 | 525 |
| 539 process.onError = (error) => completer.completeException(error); | 526 if (pipeStderr) { |
| 527 process.stderr.pipe(stderr, close: false); |
| 528 } else { |
| 529 errStream.onLine = () => processStderr.add(errStream.readLine()); |
| 530 errStream.onClosed = checkComplete; |
| 531 errStream.onError = (error) => completer.completeException(error); |
| 532 } |
| 533 |
| 534 process.onExit = (actualExitCode) { |
| 535 exitCode = actualExitCode; |
| 536 checkComplete(); |
| 537 }; |
| 538 }); |
| 539 processFuture.handleException((error) { |
| 540 completer.completeException(error); |
| 541 return true; |
| 542 }); |
| 540 | 543 |
| 541 return completer.future; | 544 return completer.future; |
| 542 } | 545 } |
| 543 | 546 |
| 544 /** | 547 /** |
| 545 * Wraps [input] to provide a timeout. If [input] completes before | 548 * Wraps [input] to provide a timeout. If [input] completes before |
| 546 * [milliseconds] have passed, then the return value completes in the same way. | 549 * [milliseconds] have passed, then the return value completes in the same way. |
| 547 * However, if [milliseconds] pass before [input] has completed, it completes | 550 * However, if [milliseconds] pass before [input] has completed, it completes |
| 548 * with a [TimeoutException] with [message]. | 551 * with a [TimeoutException] with [message]. |
| 549 * | 552 * |
| (...skipping 83 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 | 636 * 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. | 637 * directory or a path. Returns whether or not the extraction was successful. |
| 635 */ | 638 */ |
| 636 Future<bool> extractTarGz(InputStream stream, destination) { | 639 Future<bool> extractTarGz(InputStream stream, destination) { |
| 637 destination = _getPath(destination); | 640 destination = _getPath(destination); |
| 638 | 641 |
| 639 if (Platform.operatingSystem == "windows") { | 642 if (Platform.operatingSystem == "windows") { |
| 640 return _extractTarGzWindows(stream, destination); | 643 return _extractTarGzWindows(stream, destination); |
| 641 } | 644 } |
| 642 | 645 |
| 643 var process = Process.start("tar", | 646 var completer = new Completer<int>(); |
| 647 var processFuture = Process.start("tar", |
| 644 ["--extract", "--gunzip", "--directory", destination]); | 648 ["--extract", "--gunzip", "--directory", destination]); |
| 645 var completer = new Completer<int>(); | 649 processFuture.then((process) { |
| 646 | 650 process.onExit = completer.complete; |
| 647 process.onExit = completer.complete; | |
| 648 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); | 651 stream.pipe(process.stdin); |
| 654 process.stdout.pipe(stdout, close: false); | 652 process.stdout.pipe(stdout, close: false); |
| 655 process.stderr.pipe(stderr, close: false); | 653 process.stderr.pipe(stderr, close: false); |
| 656 }; | 654 }); |
| 655 processFuture.handleException((error) { |
| 656 completer.completeException(error); |
| 657 return true; |
| 658 }); |
| 657 | 659 |
| 658 return completer.future.transform((exitCode) => exitCode == 0); | 660 return completer.future.transform((exitCode) => exitCode == 0); |
| 659 } | 661 } |
| 660 | 662 |
| 661 Future<bool> _extractTarGzWindows(InputStream stream, String destination) { | 663 Future<bool> _extractTarGzWindows(InputStream stream, String destination) { |
| 662 // TODO(rnystrom): In the repo's history, there is an older implementation of | 664 // 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 | 665 // this that does everything in memory by piping streams directly together |
| 664 // instead of writing out temp files. The code is simpler, but unfortunately, | 666 // 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 | 667 // 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 | 668 // 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); | 776 return new Directory(entry); |
| 775 } | 777 } |
| 776 | 778 |
| 777 /** | 779 /** |
| 778 * Gets a [Uri] for [uri], which can either already be one, or be a [String]. | 780 * Gets a [Uri] for [uri], which can either already be one, or be a [String]. |
| 779 */ | 781 */ |
| 780 Uri _getUri(uri) { | 782 Uri _getUri(uri) { |
| 781 if (uri is Uri) return uri; | 783 if (uri is Uri) return uri; |
| 782 return new Uri.fromString(uri); | 784 return new Uri.fromString(uri); |
| 783 } | 785 } |
| OLD | NEW |