| 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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 | 364 |
| 365 // Using Path.join here instead of File().fullPathSync() because the former | 365 // Using Path.join here instead of File().fullPathSync() because the former |
| 366 // does not require an actual file to exist at that path. | 366 // does not require an actual file to exist at that path. |
| 367 return new Path.fromNative(currentWorkingDir).join(new Path(path)) | 367 return new Path.fromNative(currentWorkingDir).join(new Path(path)) |
| 368 .toNativePath(); | 368 .toNativePath(); |
| 369 } | 369 } |
| 370 | 370 |
| 371 /// Resolves [path] relative to the location of pub.dart. | 371 /// Resolves [path] relative to the location of pub.dart. |
| 372 String relativeToPub(String path) { | 372 String relativeToPub(String path) { |
| 373 var scriptPath = new File(new Options().script).fullPathSync(); | 373 var scriptPath = new File(new Options().script).fullPathSync(); |
| 374 var scriptDir = new Path.fromNative(scriptPath).directoryPath; | 374 |
| 375 return scriptDir.append(path).canonicalize().toNativePath(); | 375 // Walk up until we hit the "utils" directory. This lets us figure out where |
| 376 // we are if this function is called from pub.dart, or one of the tests, |
| 377 // which also live under "utils". |
| 378 var utilsDir = new Path.fromNative(scriptPath).directoryPath; |
| 379 while (utilsDir.filename != 'utils') { |
| 380 utilsDir = utilsDir.directoryPath; |
| 381 } |
| 382 |
| 383 return utilsDir.append('pub').append(path).canonicalize().toNativePath(); |
| 376 } | 384 } |
| 377 | 385 |
| 378 /// A StringInputStream reading from stdin. | 386 /// A StringInputStream reading from stdin. |
| 379 final _stringStdin = new StringInputStream(stdin); | 387 final _stringStdin = new StringInputStream(stdin); |
| 380 | 388 |
| 381 /// Returns a single line read from a [StringInputStream]. By default, reads | 389 /// Returns a single line read from a [StringInputStream]. By default, reads |
| 382 /// from stdin. | 390 /// from stdin. |
| 383 /// | 391 /// |
| 384 /// A [StringInputStream] passed to this should have no callbacks registered. | 392 /// A [StringInputStream] passed to this should have no callbacks registered. |
| 385 Future<String> readLine([StringInputStream stream]) { | 393 Future<String> readLine([StringInputStream stream]) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 */ | 477 */ |
| 470 Future<String> httpGetString(uri) { | 478 Future<String> httpGetString(uri) { |
| 471 var future = httpGet(uri).chain((stream) => consumeInputStream(stream)) | 479 var future = httpGet(uri).chain((stream) => consumeInputStream(stream)) |
| 472 .transform((bytes) => new String.fromCharCodes(bytes)); | 480 .transform((bytes) => new String.fromCharCodes(bytes)); |
| 473 return timeout(future, HTTP_TIMEOUT, 'fetching URL "$uri"'); | 481 return timeout(future, HTTP_TIMEOUT, 'fetching URL "$uri"'); |
| 474 } | 482 } |
| 475 | 483 |
| 476 /** | 484 /** |
| 477 * Takes all input from [source] and writes it to [sink]. | 485 * Takes all input from [source] and writes it to [sink]. |
| 478 * | 486 * |
| 479 * [onClosed] is called when [source] is closed. | 487 * Returns a future that completes when [source] is closed. |
| 480 */ | 488 */ |
| 481 void pipeInputToInput(InputStream source, ListInputStream sink, | 489 Future pipeInputToInput(InputStream source, ListInputStream sink) { |
| 482 [void onClosed()]) { | 490 var completer = new Completer(); |
| 483 source.onClosed = () { | 491 source.onClosed = () { |
| 484 sink.markEndOfStream(); | 492 sink.markEndOfStream(); |
| 485 if (onClosed != null) onClosed(); | 493 completer.complete(null); |
| 486 }; | 494 }; |
| 487 source.onData = () => sink.write(source.read()); | 495 source.onData = () => sink.write(source.read()); |
| 488 // TODO(nweiz): propagate this error to the sink. See issue 3657. | 496 // TODO(nweiz): propagate this error to the sink. See issue 3657. |
| 489 source.onError = (e) { throw e; }; | 497 source.onError = (e) { throw e; }; |
| 498 return completer.future; |
| 490 } | 499 } |
| 491 | 500 |
| 492 /** | 501 /** |
| 493 * Buffers all input from an InputStream and returns it as a future. | 502 * Buffers all input from an InputStream and returns it as a future. |
| 494 */ | 503 */ |
| 495 Future<List<int>> consumeInputStream(InputStream stream) { | 504 Future<List<int>> consumeInputStream(InputStream stream) { |
| 496 if (stream.closed) return new Future.immediate(<int>[]); | 505 if (stream.closed) return new Future.immediate(<int>[]); |
| 497 | 506 |
| 498 var completer = new Completer<List<int>>(); | 507 var completer = new Completer<List<int>>(); |
| 499 var buffer = <int>[]; | 508 var buffer = <int>[]; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 completer.complete(value); | 630 completer.complete(value); |
| 622 }); | 631 }); |
| 623 return completer.future; | 632 return completer.future; |
| 624 } | 633 } |
| 625 | 634 |
| 626 /// Creates a temporary directory and passes its path to [fn]. Once the [Future] | 635 /// Creates a temporary directory and passes its path to [fn]. Once the [Future] |
| 627 /// returned by [fn] completes, the temporary directory and all its contents | 636 /// returned by [fn] completes, the temporary directory and all its contents |
| 628 /// will be deleted. | 637 /// will be deleted. |
| 629 Future withTempDir(Future fn(String path)) { | 638 Future withTempDir(Future fn(String path)) { |
| 630 var tempDir; | 639 var tempDir; |
| 631 var future = new Directory('').createTemp().chain((dir) { | 640 var future = createTempDir().chain((dir) { |
| 632 tempDir = dir; | 641 tempDir = dir; |
| 633 return fn(tempDir.path); | 642 return fn(tempDir.path); |
| 634 }); | 643 }); |
| 635 future.onComplete((_) => tempDir.delete(recursive: true)); | 644 future.onComplete((_) => tempDir.delete(recursive: true)); |
| 636 return future; | 645 return future; |
| 637 } | 646 } |
| 638 | 647 |
| 639 /// Tests whether or not the git command-line app is available for use. | 648 /// Tests whether or not the git command-line app is available for use. |
| 640 Future<bool> get isGitInstalled { | 649 Future<bool> get isGitInstalled { |
| 641 if (_isGitInstalledCache != null) { | 650 if (_isGitInstalledCache != null) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 // read from stdin instead of a file. Consider resurrecting that version if | 743 // read from stdin instead of a file. Consider resurrecting that version if |
| 735 // we can figure out why it fails. | 744 // we can figure out why it fails. |
| 736 | 745 |
| 737 // Note: This line of code gets munged by create_sdk.py to be the correct | 746 // Note: This line of code gets munged by create_sdk.py to be the correct |
| 738 // relative path to 7zip in the SDK. | 747 // relative path to 7zip in the SDK. |
| 739 var pathTo7zip = '../../third_party/7zip/7za.exe'; | 748 var pathTo7zip = '../../third_party/7zip/7za.exe'; |
| 740 var command = relativeToPub(pathTo7zip); | 749 var command = relativeToPub(pathTo7zip); |
| 741 | 750 |
| 742 var tempDir; | 751 var tempDir; |
| 743 | 752 |
| 753 // TODO(rnystrom): Use withTempDir(). |
| 744 return createTempDir().chain((temp) { | 754 return createTempDir().chain((temp) { |
| 745 // Write the archive to a temp file. | 755 // Write the archive to a temp file. |
| 746 tempDir = temp; | 756 tempDir = temp; |
| 747 return createFileFromStream(stream, join(tempDir, 'data.tar.gz')); | 757 return createFileFromStream(stream, join(tempDir, 'data.tar.gz')); |
| 748 }).chain((_) { | 758 }).chain((_) { |
| 749 // 7zip can't unarchive from gzip -> tar -> destination all in one step | 759 // 7zip can't unarchive from gzip -> tar -> destination all in one step |
| 750 // first we un-gzip it to a tar file. | 760 // first we un-gzip it to a tar file. |
| 751 // Note: Setting the working directory instead of passing in a full file | 761 // Note: Setting the working directory instead of passing in a full file |
| 752 // path because 7zip says "A full path is not allowed here." | 762 // path because 7zip says "A full path is not allowed here." |
| 753 return runProcess(command, ['e', 'data.tar.gz'], workingDir: tempDir); | 763 return runProcess(command, ['e', 'data.tar.gz'], workingDir: tempDir); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 // Create the tar file. | 832 // Create the tar file. |
| 823 var tarFile = join(tempDir, "intermediate.tar"); | 833 var tarFile = join(tempDir, "intermediate.tar"); |
| 824 var args = ["a", "-w$baseDir", tarFile]; | 834 var args = ["a", "-w$baseDir", tarFile]; |
| 825 args.addAll(contents.map((entry) => '-i!"$entry"')); | 835 args.addAll(contents.map((entry) => '-i!"$entry"')); |
| 826 | 836 |
| 827 // Note: This line of code gets munged by create_sdk.py to be the correct | 837 // Note: This line of code gets munged by create_sdk.py to be the correct |
| 828 // relative path to 7zip in the SDK. | 838 // relative path to 7zip in the SDK. |
| 829 var pathTo7zip = '../../third_party/7zip/7za.exe'; | 839 var pathTo7zip = '../../third_party/7zip/7za.exe'; |
| 830 var command = relativeToPub(pathTo7zip); | 840 var command = relativeToPub(pathTo7zip); |
| 831 | 841 |
| 832 return runProcess(command, args).chain((_) { | 842 // We're passing 'baseDir' both as '-w' and setting it as the working |
| 843 // directory explicitly here intentionally. The former ensures that the |
| 844 // files added to the archive have the correct relative path in the archive. |
| 845 // The latter enables relative paths in the "-i" args to be resolved. |
| 846 return runProcess(command, args, workingDir: baseDir).chain((_) { |
| 833 // GZIP it. 7zip doesn't support doing both as a single operation. Send | 847 // GZIP it. 7zip doesn't support doing both as a single operation. Send |
| 834 // the output to stdout. | 848 // the output to stdout. |
| 835 args = ["a", "not used", "-so", tarFile]; | 849 args = ["a", "unused", "-tgzip", "-so", tarFile]; |
| 836 return startProcess(command, args); | 850 return startProcess(command, args); |
| 837 }).transform((process) { | 851 }).chain((process) { |
| 838 pipeInputToInput(process.stdout, stream); | |
| 839 process.stderr.pipe(stderr, close: false); | 852 process.stderr.pipe(stderr, close: false); |
| 853 return pipeInputToInput(process.stdout, stream); |
| 840 }); | 854 }); |
| 841 }); | 855 }); |
| 842 return stream; | 856 return stream; |
| 843 } | 857 } |
| 844 | 858 |
| 845 /** | 859 /** |
| 846 * Exception thrown when an HTTP operation fails. | 860 * Exception thrown when an HTTP operation fails. |
| 847 */ | 861 */ |
| 848 class PubHttpException implements Exception { | 862 class PubHttpException implements Exception { |
| 849 final int statusCode; | 863 final int statusCode; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 return new Directory(entry); | 923 return new Directory(entry); |
| 910 } | 924 } |
| 911 | 925 |
| 912 /** | 926 /** |
| 913 * Gets a [Uri] for [uri], which can either already be one, or be a [String]. | 927 * Gets a [Uri] for [uri], which can either already be one, or be a [String]. |
| 914 */ | 928 */ |
| 915 Uri _getUri(uri) { | 929 Uri _getUri(uri) { |
| 916 if (uri is Uri) return uri; | 930 if (uri is Uri) return uri; |
| 917 return new Uri.fromString(uri); | 931 return new Uri.fromString(uri); |
| 918 } | 932 } |
| OLD | NEW |