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

Unified Diff: utils/pub/io.dart

Issue 10937019: First pass at getting git and tar.gz working on Windows. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix merge bug. 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 | « tools/create_sdk.py ('k') | utils/tests/pub/pub.status » ('j') | 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 3f281d6fb1b2cec792c963dd39055c46be9b2da8..e39a9ccbe08c9fce5fc9d1310e3c390526db13ea 100644
--- a/utils/pub/io.dart
+++ b/utils/pub/io.dart
@@ -10,8 +10,14 @@
#import('dart:io');
#import('dart:isolate');
#import('dart:uri');
+
#import('utils.dart');
+bool _isGitInstalledCache;
+
+/// The cached Git command.
+String _gitCommandCache;
+
/** Gets the current working directory. */
String get workingDir => new File('.').fullPathSync();
@@ -270,8 +276,8 @@ Future<File> createSymlink(from, to) {
// command is not.) I'm using a junction point (/j) here instead of a soft
// link (/d) because the latter requires some privilege shenanigans that
// I'm not sure how to specify from the command line.
- command = 'cmd';
- args = ['/c', 'mklink', '/j', to, from];
+ command = 'mklink';
+ args = ['/j', to, from];
}
return runProcess(command, args).transform((result) {
@@ -365,7 +371,8 @@ Future<InputStream> httpGet(uri) {
if (e is SocketIOException &&
(e.osError.errorCode == 8 ||
e.osError.errorCode == -2 ||
- e.osError.errorCode == -5)) {
+ e.osError.errorCode == -5 ||
+ e.osError.errorCode == 11004)) {
e = 'Could not resolve URL "${uri.origin}".';
}
@@ -439,6 +446,16 @@ Future<PubProcessResult> runProcess(String executable, List<String> args,
bool pipeStderr = false]) {
int exitCode;
+ // TODO(rnystrom): Should dart:io just handle this?
+ // Spawning a process on Windows will not look for the executable in the
+ // system path. So, if executable looks like it needs that (i.e. it doesn't
+ // have any path separators in it), then spawn it through a shell.
+ if ((Platform.operatingSystem == "windows") &&
+ (executable.indexOf('\\') == -1)) {
+ args = flatten(["/c", executable, args]);
+ executable = "cmd";
+ }
+
final options = new ProcessOptions();
if (workingDir != null) {
options.workingDirectory = _getDirectory(workingDir).path;
@@ -520,15 +537,20 @@ Future timeout(Future input, int milliSeconds, String message) {
return completer.future;
}
-/// The cached Git command.
-String _gitCommandCache;
-
/// Tests whether or not the git command-line app is available for use.
-Future<bool> get isGitInstalled => _gitCommand.transform((git) => git != null);
+Future<bool> get isGitInstalled {
+ if (_isGitInstalledCache != null) {
+ // TODO(rnystrom): The sleep is to pump the message queue. Can use
+ // Future.immediate() when #3356 is fixed.
+ return sleep(0).transform((_) => _isGitInstalledCache);
+
+ return _gitCommand.transform((git) => git != null);
+ }
+}
/// Run a git process with [args] from [workingDir].
Future<PubProcessResult> runGit(List<String> args, [String workingDir]) =>
- _gitCommand.chain((git) => runProcess(git, args, workingDir));
+ _gitCommand.chain((git) => runProcess(git, args, workingDir));
/// Returns the name of the git command-line app, or null if Git could not be
/// found on the user's PATH.
@@ -579,8 +601,14 @@ Future<bool> _tryGitCommand(String command) {
* directory or a path. Returns whether or not the extraction was successful.
*/
Future<bool> extractTarGz(InputStream stream, destination) {
+ destination = _getPath(destination);
+
+ if (Platform.operatingSystem == "windows") {
+ return _extractTarGzWindows(stream, destination);
+ }
+
var process = Process.start("tar",
- ["--extract", "--gunzip", "--directory", _getPath(destination)]);
+ ["--extract", "--gunzip", "--directory", destination]);
var completer = new Completer<int>();
// Wait for the process to be fully started before writing to its
@@ -597,6 +625,33 @@ Future<bool> extractTarGz(InputStream stream, destination) {
return completer.future.transform((exitCode) => exitCode == 0);
}
+Future<bool> _extractTarGzWindows(InputStream stream, String destination) {
+ // Find 7zip.
+ var scriptDir = new Path(new Options().script).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();
+
+ // 7zip can't unarchive from gzip -> tar -> destination all in one step so
+ // we spawn it twice and pipe them together.
+ var completer = new Completer<int>();
+ var gzipProcess = Process.start(command, ["e", "-si", "-tgzip", '-so']);
+ var tarProcess = Process.start(command,
+ ["e", "-si", "-ttar", '-o"$destination"']);
+
+ stream.pipe(gzipProcess.stdin);
+ gzipProcess.stdout.pipe(tarProcess.stdin);
+
+ tarProcess.onExit = completer.complete;
+ gzipProcess.onError = completer.completeException;
+ gzipProcess.onError = completer.completeException;
+
+ return completer.future.transform((exitCode) => exitCode == 0);
+}
+
/**
* Exception thrown when an HTTP operation fails.
*/
« no previous file with comments | « tools/create_sdk.py ('k') | utils/tests/pub/pub.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698