Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(590)

Unified Diff: utils/pub/io.dart

Issue 11031015: Extract archives by writing .tar.gz to temp file on Windows. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698