Index: utils/pub/io.dart |
diff --git a/utils/pub/io.dart b/utils/pub/io.dart |
index 59aa7b43dc28ee6842d8612838ac5afb2a5a9622..68453c69a684cad32db5a871a00172a117ebe362 100644 |
--- a/utils/pub/io.dart |
+++ b/utils/pub/io.dart |
@@ -371,8 +371,16 @@ String getFullPath(entry) { |
/// Resolves [path] relative to the location of pub.dart. |
String relativeToPub(String path) { |
var scriptPath = new File(new Options().script).fullPathSync(); |
- var scriptDir = new Path.fromNative(scriptPath).directoryPath; |
- return scriptDir.append(path).canonicalize().toNativePath(); |
+ |
+ // Walk up until we hit the "utils" directory. This lets us figure out where |
+ // we are if this function is called from pub.dart, or one of the tests, |
+ // which also live under "utils". |
+ var utilsDir = new Path.fromNative(scriptPath).directoryPath; |
+ while (utilsDir.filename != 'utils') { |
+ utilsDir = utilsDir.directoryPath; |
nweiz
2012/11/28 23:37:55
We should have a reasonable error message if this
Bob Nystrom
2012/11/29 00:16:11
Yeah, I'm not sure exactly how this will fail, but
|
+ } |
+ |
+ return utilsDir.append('pub').append(path).canonicalize().toNativePath(); |
} |
/// A StringInputStream reading from stdin. |
@@ -476,17 +484,18 @@ Future<String> httpGetString(uri) { |
/** |
* Takes all input from [source] and writes it to [sink]. |
* |
- * [onClosed] is called when [source] is closed. |
+ * Returns a future that completes when [source] is closed. |
*/ |
-void pipeInputToInput(InputStream source, ListInputStream sink, |
- [void onClosed()]) { |
+Future pipeInputToInput(InputStream source, ListInputStream sink) { |
+ var completer = new Completer(); |
source.onClosed = () { |
sink.markEndOfStream(); |
- if (onClosed != null) onClosed(); |
+ completer.complete(null); |
}; |
source.onData = () => sink.write(source.read()); |
// TODO(nweiz): propagate this error to the sink. See issue 3657. |
source.onError = (e) { throw e; }; |
+ return completer.future; |
} |
/** |
@@ -612,7 +621,7 @@ Future timeout(Future input, int milliseconds, String description) { |
/// will be deleted. |
Future withTempDir(Future fn(String path)) { |
var tempDir; |
- var future = new Directory('').createTemp().chain((dir) { |
+ var future = createTempDir().chain((dir) { |
tempDir = dir; |
return fn(tempDir.path); |
}); |
@@ -725,6 +734,7 @@ Future<bool> _extractTarGzWindows(InputStream stream, String destination) { |
var tempDir; |
+ // TODO(rnystrom): Use withTempDir(). |
return createTempDir().chain((temp) { |
// Write the archive to a temp file. |
tempDir = temp; |
@@ -813,14 +823,18 @@ InputStream createTarGz(List contents, {baseDir}) { |
var pathTo7zip = '../../third_party/7zip/7za.exe'; |
var command = relativeToPub(pathTo7zip); |
- return runProcess(command, args).chain((_) { |
+ // We're passing 'baseDir' both as '-w' and setting it as the working |
+ // directory explicitly here intentionally. The former ensures that the |
+ // files added to the archive have the correct relative path in the archive. |
+ // The latter enables relative paths in the "-i" args to be resolved. |
+ return runProcess(command, args, workingDir: baseDir).chain((_) { |
// GZIP it. 7zip doesn't support doing both as a single operation. Send |
// the output to stdout. |
- args = ["a", "not used", "-so", tarFile]; |
+ args = ["a", "unused", "-tgzip", "-so", tarFile]; |
return startProcess(command, args); |
- }).transform((process) { |
- pipeInputToInput(process.stdout, stream); |
+ }).chain((process) { |
process.stderr.pipe(stderr, close: false); |
+ return pipeInputToInput(process.stdout, stream); |
}); |
}); |
return stream; |