| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 /// Helper functionality to make working with IO easier. | 5 /// Helper functionality to make working with IO easier. |
| 6 library pub.io; | 6 library pub.io; |
| 7 | 7 |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:collection'; | 9 import 'dart:collection'; |
| 10 import 'dart:convert'; | 10 import 'dart:convert'; |
| (...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 926 } | 926 } |
| 927 | 927 |
| 928 /// Create a .tar.gz archive from a list of entries. | 928 /// Create a .tar.gz archive from a list of entries. |
| 929 /// | 929 /// |
| 930 /// Each entry can be a [String], [Directory], or [File] object. The root of | 930 /// Each entry can be a [String], [Directory], or [File] object. The root of |
| 931 /// the archive is considered to be [baseDir], which defaults to the current | 931 /// the archive is considered to be [baseDir], which defaults to the current |
| 932 /// working directory. | 932 /// working directory. |
| 933 /// | 933 /// |
| 934 /// Returns a [ByteStream] that emits the contents of the archive. | 934 /// Returns a [ByteStream] that emits the contents of the archive. |
| 935 ByteStream createTarGz(List contents, {baseDir}) { | 935 ByteStream createTarGz(List contents, {baseDir}) { |
| 936 return new ByteStream(futureStream(new Future.sync(() { | 936 return new ByteStream(futureStream(new Future.sync(() async { |
| 937 var buffer = new StringBuffer(); | 937 var buffer = new StringBuffer(); |
| 938 buffer.write('Creating .tag.gz stream containing:\n'); | 938 buffer.write('Creating .tag.gz stream containing:\n'); |
| 939 contents.forEach((file) => buffer.write('$file\n')); | 939 contents.forEach((file) => buffer.write('$file\n')); |
| 940 log.fine(buffer.toString()); | 940 log.fine(buffer.toString()); |
| 941 | 941 |
| 942 if (baseDir == null) baseDir = path.current; | 942 if (baseDir == null) baseDir = path.current; |
| 943 baseDir = path.absolute(baseDir); | 943 baseDir = path.absolute(baseDir); |
| 944 contents = contents.map((entry) { | 944 contents = contents.map((entry) { |
| 945 entry = path.absolute(entry); | 945 entry = path.absolute(entry); |
| 946 if (!path.isWithin(baseDir, entry)) { | 946 if (!path.isWithin(baseDir, entry)) { |
| 947 throw new ArgumentError('Entry $entry is not inside $baseDir.'); | 947 throw new ArgumentError('Entry $entry is not inside $baseDir.'); |
| 948 } | 948 } |
| 949 return path.relative(entry, from: baseDir); | 949 return path.relative(entry, from: baseDir); |
| 950 }).toList(); | 950 }).toList(); |
| 951 | 951 |
| 952 if (Platform.operatingSystem != "windows") { | 952 if (Platform.operatingSystem != "windows") { |
| 953 var args = ["--create", "--gzip", "--directory", baseDir]; | 953 var args = [ |
| 954 args.addAll(contents); | 954 "--create", |
| 955 // TODO(nweiz): It's possible that enough command-line arguments will | 955 "--gzip", |
| 956 // make the process choke, so at some point we should save the arguments | 956 "--directory", |
| 957 // to a file and pass them in via --files-from for tar and -i@filename | 957 baseDir, |
| 958 // for 7zip. | 958 "--files-from", |
| 959 return startProcess("tar", args).then((process) => process.stdout); | 959 "/dev/stdin" |
| 960 ]; |
| 961 |
| 962 var process = await startProcess("tar", args); |
| 963 process.stdin.add(UTF8.encode(contents.join("\n"))); |
| 964 process.stdin.close(); |
| 965 return process.stdout; |
| 960 } | 966 } |
| 961 | 967 |
| 962 // Don't use [withTempDir] here because we don't want to delete the temp | 968 // Don't use [withTempDir] here because we don't want to delete the temp |
| 963 // directory until the returned stream has closed. | 969 // directory until the returned stream has closed. |
| 964 var tempDir = createSystemTempDir(); | 970 var tempDir = createSystemTempDir(); |
| 965 return new Future.sync(() { | 971 |
| 972 try { |
| 973 // Create the file containing the list of files to compress. |
| 974 var contentsPath = path.join(tempDir, "files.txt"); |
| 975 writeTextFile(contentsPath, contents.join("\n")); |
| 976 |
| 966 // Create the tar file. | 977 // Create the tar file. |
| 967 var tarFile = path.join(tempDir, "intermediate.tar"); | 978 var tarFile = path.join(tempDir, "intermediate.tar"); |
| 968 var args = ["a", "-w$baseDir", tarFile]; | 979 var args = ["a", "-w$baseDir", tarFile, "@$contentsPath"]; |
| 969 args.addAll(contents.map((entry) => '-i!$entry')); | |
| 970 | 980 |
| 971 // We're passing 'baseDir' both as '-w' and setting it as the working | 981 // We're passing 'baseDir' both as '-w' and setting it as the working |
| 972 // directory explicitly here intentionally. The former ensures that the | 982 // directory explicitly here intentionally. The former ensures that the |
| 973 // files added to the archive have the correct relative path in the | 983 // files added to the archive have the correct relative path in the |
| 974 // archive. The latter enables relative paths in the "-i" args to be | 984 // archive. The latter enables relative paths in the "-i" args to be |
| 975 // resolved. | 985 // resolved. |
| 976 return runProcess(pathTo7zip, args, workingDir: baseDir).then((_) { | 986 await runProcess(pathTo7zip, args, workingDir: baseDir); |
| 977 // GZIP it. 7zip doesn't support doing both as a single operation. | 987 |
| 978 // Send the output to stdout. | 988 // GZIP it. 7zip doesn't support doing both as a single operation. |
| 979 args = ["a", "unused", "-tgzip", "-so", tarFile]; | 989 // Send the output to stdout. |
| 980 return startProcess(pathTo7zip, args); | 990 args = ["a", "unused", "-tgzip", "-so", tarFile]; |
| 981 }).then((process) => process.stdout); | 991 return (await startProcess(pathTo7zip, args)) |
| 982 }).then((stream) { | 992 .stdout |
| 983 return stream.transform(onDoneTransformer(() => deleteEntry(tempDir))); | 993 .transform(onDoneTransformer(() => deleteEntry(tempDir))); |
| 984 }).catchError((e) { | 994 } catch (_) { |
| 985 deleteEntry(tempDir); | 995 deleteEntry(tempDir); |
| 986 throw e; | 996 rethrow; |
| 987 }); | 997 } |
| 988 }))); | 998 }))); |
| 989 } | 999 } |
| 990 | 1000 |
| 991 /// Contains the results of invoking a [Process] and waiting for it to complete. | 1001 /// Contains the results of invoking a [Process] and waiting for it to complete. |
| 992 class PubProcessResult { | 1002 class PubProcessResult { |
| 993 final List<String> stdout; | 1003 final List<String> stdout; |
| 994 final List<String> stderr; | 1004 final List<String> stderr; |
| 995 final int exitCode; | 1005 final int exitCode; |
| 996 | 1006 |
| 997 PubProcessResult(String stdout, String stderr, this.exitCode) | 1007 PubProcessResult(String stdout, String stderr, this.exitCode) |
| 998 : this.stdout = _toLines(stdout), | 1008 : this.stdout = _toLines(stdout), |
| 999 this.stderr = _toLines(stderr); | 1009 this.stderr = _toLines(stderr); |
| 1000 | 1010 |
| 1001 // TODO(rnystrom): Remove this and change to returning one string. | 1011 // TODO(rnystrom): Remove this and change to returning one string. |
| 1002 static List<String> _toLines(String output) { | 1012 static List<String> _toLines(String output) { |
| 1003 var lines = splitLines(output); | 1013 var lines = splitLines(output); |
| 1004 if (!lines.isEmpty && lines.last == "") lines.removeLast(); | 1014 if (!lines.isEmpty && lines.last == "") lines.removeLast(); |
| 1005 return lines; | 1015 return lines; |
| 1006 } | 1016 } |
| 1007 | 1017 |
| 1008 bool get success => exitCode == exit_codes.SUCCESS; | 1018 bool get success => exitCode == exit_codes.SUCCESS; |
| 1009 } | 1019 } |
| 1010 | 1020 |
| 1011 /// Gets a [Uri] for [uri], which can either already be one, or be a [String]. | 1021 /// Gets a [Uri] for [uri], which can either already be one, or be a [String]. |
| 1012 Uri _getUri(uri) { | 1022 Uri _getUri(uri) { |
| 1013 if (uri is Uri) return uri; | 1023 if (uri is Uri) return uri; |
| 1014 return Uri.parse(uri); | 1024 return Uri.parse(uri); |
| 1015 } | 1025 } |
| OLD | NEW |