Chromium Code Reviews| Index: utils/pub/io.dart |
| diff --git a/utils/pub/io.dart b/utils/pub/io.dart |
| index 38a4c48680f66438fb67489d0e2b7032ec028ef0..4098f4ce8d557cc312fbd45463c3eb8d59dcedb9 100644 |
| --- a/utils/pub/io.dart |
| +++ b/utils/pub/io.dart |
| @@ -140,6 +140,27 @@ Future<File> deleteFile(file) { |
| return new File(_getPath(file)).delete(); |
| } |
| +/// Writes [stream] to a new file at [path], which may be a [String] or a |
| +/// [File]. Will replace any file already at that path. Completes when the file |
| +/// is done being written. |
| +Future<File> createFileFromStream(InputStream stream, path) { |
| + path = _getPath(path); |
| + |
| + var completer = new Completer<File>(); |
| + var file = new File(path); |
| + var outputStream = file.openOutputStream(); |
| + stream.pipe(outputStream); |
| + |
| + outputStream.onClosed = () { |
| + completer.complete(file); |
| + }; |
| + |
| + stream.onError = completer.completeException; |
| + outputStream.onError = completer.completeException; |
|
nweiz
2012/10/02 01:04:13
It's possible that both streams could throw errors
Bob Nystrom
2012/10/02 01:36:37
Done.
|
| + |
| + return completer.future; |
| +} |
| + |
| /** |
| * Creates a directory [dir]. Returns a [Future] that completes when the |
| * directory is created. |
| @@ -634,6 +655,69 @@ Future<bool> _extractTarGzWindows(InputStream stream, String destination) { |
| // Note: This line of code gets munged by create_sdk.py to be the correct |
| // relative path to 7zip in the SDK. |
| var pathTo7zip = '../../third_party/7zip/7za.exe'; |
| + var command = scriptDir.append(pathTo7zip).canonicalize().toNativePath(); |
| + |
| + var tempDir; |
| + |
| + return createTempDir().chain((temp) { |
| + // Write the archive to a temp file. |
| + tempDir = temp; |
| + return createFileFromStream(stream, join(tempDir, 'data.tar.gz')); |
| + }).chain((tarGz) { |
| + // 7zip can't unarchive from gzip -> tar -> destination all in one step |
| + // first we un-gzip it to a tar file. |
| + // TODO(rnystrom): Setting the working directory instead of passing in |
|
nweiz
2012/10/02 01:04:13
I don't know if this is really a TODO, since you c
Bob Nystrom
2012/10/02 01:36:37
Done.
|
| + // a full file path because 7zip says "A full path is not allowed here." |
| + return runProcess(command, ['e', 'data.tar.gz'], workingDir: tempDir); |
| + }).chain((result) { |
| + if (result.exitCode != 0) { |
| + throw 'Could not un-gzip (exit code ${result.exitCode}). Error:\n' |
| + '${Strings.join(result.stderr, "\n")}'; |
| + } |
| + |
| + // Find the tar file we just created since we don't know its name. |
| + return listDir(tempDir); |
| + }).chain((files) { |
| + var tarFile; |
| + for (var file in files) { |
| + if (new Path(file).extension == 'tar') { |
| + tarFile = file; |
| + break; |
| + } |
| + } |
| + |
| + if (tarFile == null) throw 'The gzip file did not contain a tar file.'; |
| + |
| + // Untar the archive into the destination directory. |
| + return runProcess(command, ['x', '-o"$destination"', tarFile], |
| + workingDir: tempDir); |
| + }).chain((result) { |
| + if (result.exitCode != 0) { |
| + throw 'Could not un-tar (exit code ${result.exitCode}). Error:\n' |
| + '${Strings.join(result.stderr, "\n")}'; |
| + } |
| + |
| + // Clean up the temp directory. |
| + // TODO(rnystrom): Should also delete this if anything fails. |
| + return deleteDir(tempDir); |
| + }).transform((_) => true); |
| +} |
| + |
| +// TODO(rnystrom): The following is a cleaner way of extracting archives on |
| +// Windows. It does everything in memory by piping streams directly together |
| +// instead of writing out temp files. Unfortunately, 7zip seems to periodically |
| +// fail when we invoke it from Dart and tell it to read from stdin instead of |
| +// a file. Leaving this code here since it's otherwise cleaner, and maybe we |
| +// can resurrect it at some point. |
| +/* |
|
nweiz
2012/10/02 01:04:13
I don't like checking in commented-out code. I fee
Bob Nystrom
2012/10/02 01:36:37
Done.
|
| +Future<bool> _extractTarGzWindows(InputStream stream, String destination) { |
| + // Find 7zip. |
| + var scriptPath = new File(new Options().script).fullPathSync(); |
| + var scriptDir = new Path.fromNative(scriptPath).directoryPath; |
| + |
| + // Note: This line of code gets munged by create_sdk.py to be the correct |
| + // relative path to 7zip in the SDK. |
| + var pathTo7zip = '../../third_party/7zip/7za.exe'; |
| var command = scriptDir.append(pathTo7zip).canonicalize().toNativePath(); |
| @@ -682,6 +766,7 @@ Future<bool> _extractTarGzWindows(InputStream stream, String destination) { |
| return completer.future; |
| } |
| +*/ |
| /** |
| * Exception thrown when an HTTP operation fails. |