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

Side by Side Diff: utils/pub/io.dart

Issue 12225085: Make createTempDir() synchronous. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « utils/pub/hosted_source.dart ('k') | utils/pub/system_cache.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 io; 6 library io;
7 7
8 import 'dart:async'; 8 import 'dart:async';
9 import 'dart:io'; 9 import 'dart:io';
10 import 'dart:isolate'; 10 import 'dart:isolate';
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 } 150 }
151 } 151 }
152 152
153 return dir; 153 return dir;
154 } 154 }
155 155
156 /// Creates a temp directory whose name will be based on [dir] with a unique 156 /// Creates a temp directory whose name will be based on [dir] with a unique
157 /// suffix appended to it. If [dir] is not provided, a temp directory will be 157 /// suffix appended to it. If [dir] is not provided, a temp directory will be
158 /// created in a platform-dependent temporary location. Returns a [Future] that 158 /// created in a platform-dependent temporary location. Returns a [Future] that
159 /// completes when the directory is created. 159 /// completes when the directory is created.
160 Future<Directory> createTempDir([dir = '']) { 160 Directory createTempDir([dir = '']) {
161 dir = _getDirectory(dir); 161 var tempDir = _getDirectory(dir).createTempSync();
162 return log.ioAsync("create temp directory ${dir.path}", 162 log.io("Created temp directory ${tempDir.path}");
163 dir.createTemp()); 163 return tempDir;
164 } 164 }
165 165
166 /// Asynchronously recursively deletes [dir], which can be a [String] or a 166 /// Asynchronously recursively deletes [dir], which can be a [String] or a
167 /// [Directory]. Returns a [Future] that completes when the deletion is done. 167 /// [Directory]. Returns a [Future] that completes when the deletion is done.
168 Future<Directory> deleteDir(dir) { 168 Future<Directory> deleteDir(dir) {
169 dir = _getDirectory(dir); 169 dir = _getDirectory(dir);
170 170
171 return _attemptRetryable(() => log.ioAsync("delete directory ${dir.path}", 171 return _attemptRetryable(() => log.ioAsync("delete directory ${dir.path}",
172 dir.delete(recursive: true))); 172 dir.delete(recursive: true)));
173 } 173 }
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 if (completed) return; 715 if (completed) return;
716 timer.cancel(); 716 timer.cancel();
717 completer.completeError(e.error, e.stackTrace); 717 completer.completeError(e.error, e.stackTrace);
718 }); 718 });
719 return completer.future; 719 return completer.future;
720 } 720 }
721 721
722 /// Creates a temporary directory and passes its path to [fn]. Once the [Future] 722 /// Creates a temporary directory and passes its path to [fn]. Once the [Future]
723 /// returned by [fn] completes, the temporary directory and all its contents 723 /// returned by [fn] completes, the temporary directory and all its contents
724 /// will be deleted. 724 /// will be deleted.
725 ///
726 /// Returns a future that completes to the value that the future returned from
727 /// [fn] completes to.
725 Future withTempDir(Future fn(String path)) { 728 Future withTempDir(Future fn(String path)) {
726 var tempDir; 729 return defer(() {
727 return createTempDir().then((dir) { 730 var tempDir = createTempDir();
728 tempDir = dir; 731 return fn(tempDir.path).whenComplete(() {
729 return fn(tempDir.path); 732 return deleteDir(tempDir);
730 }).whenComplete(() { 733 });
731 log.fine('Cleaning up temp directory ${tempDir.path}.');
732 return deleteDir(tempDir);
733 }); 734 });
734 } 735 }
735 736
736 /// Extracts a `.tar.gz` file from [stream] to [destination], which can be a 737 /// Extracts a `.tar.gz` file from [stream] to [destination], which can be a
737 /// directory or a path. Returns whether or not the extraction was successful. 738 /// directory or a path. Returns whether or not the extraction was successful.
738 Future<bool> extractTarGz(Stream<List<int>> stream, destination) { 739 Future<bool> extractTarGz(Stream<List<int>> stream, destination) {
739 destination = _getPath(destination); 740 destination = _getPath(destination);
740 741
741 log.fine("Extracting .tar.gz stream to $destination."); 742 log.fine("Extracting .tar.gz stream to $destination.");
742 743
(...skipping 29 matching lines...) Expand all
772 // instead of writing out temp files. The code is simpler, but unfortunately, 773 // instead of writing out temp files. The code is simpler, but unfortunately,
773 // 7zip seems to periodically fail when we invoke it from Dart and tell it to 774 // 7zip seems to periodically fail when we invoke it from Dart and tell it to
774 // read from stdin instead of a file. Consider resurrecting that version if 775 // read from stdin instead of a file. Consider resurrecting that version if
775 // we can figure out why it fails. 776 // we can figure out why it fails.
776 777
777 // Note: This line of code gets munged by create_sdk.py to be the correct 778 // Note: This line of code gets munged by create_sdk.py to be the correct
778 // relative path to 7zip in the SDK. 779 // relative path to 7zip in the SDK.
779 var pathTo7zip = '../../third_party/7zip/7za.exe'; 780 var pathTo7zip = '../../third_party/7zip/7za.exe';
780 var command = relativeToPub(pathTo7zip); 781 var command = relativeToPub(pathTo7zip);
781 782
782 var tempDir; 783 return withTempDir((tempDir) {
784 // Write the archive to a temp file.
785 return createFileFromStream(stream, join(tempDir, 'data.tar.gz')).then((_) {
786 // 7zip can't unarchive from gzip -> tar -> destination all in one step
787 // first we un-gzip it to a tar file.
788 // Note: Setting the working directory instead of passing in a full file
789 // path because 7zip says "A full path is not allowed here."
790 return runProcess(command, ['e', 'data.tar.gz'], workingDir: tempDir);
791 }).then((result) {
792 if (result.exitCode != 0) {
793 throw 'Could not un-gzip (exit code ${result.exitCode}). Error:\n'
794 '${Strings.join(result.stdout, "\n")}\n'
795 '${Strings.join(result.stderr, "\n")}';
796 }
797 // Find the tar file we just created since we don't know its name.
798 return listDir(tempDir);
799 }).then((files) {
800 var tarFile;
801 for (var file in files) {
802 if (path.extension(file) == '.tar') {
803 tarFile = file;
804 break;
805 }
806 }
783 807
784 // TODO(rnystrom): Use withTempDir(). 808 if (tarFile == null) throw 'The gzip file did not contain a tar file.';
785 return createTempDir().then((temp) { 809
786 // Write the archive to a temp file. 810 // Untar the archive into the destination directory.
787 tempDir = temp; 811 return runProcess(command, ['x', tarFile], workingDir: destination);
788 return createFileFromStream(stream, join(tempDir, 'data.tar.gz')); 812 }).then((result) {
789 }).then((_) { 813 if (result.exitCode != 0) {
790 // 7zip can't unarchive from gzip -> tar -> destination all in one step 814 throw 'Could not un-tar (exit code ${result.exitCode}). Error:\n'
791 // first we un-gzip it to a tar file. 815 '${Strings.join(result.stdout, "\n")}\n'
792 // Note: Setting the working directory instead of passing in a full file 816 '${Strings.join(result.stderr, "\n")}';
793 // path because 7zip says "A full path is not allowed here."
794 return runProcess(command, ['e', 'data.tar.gz'], workingDir: tempDir);
795 }).then((result) {
796 if (result.exitCode != 0) {
797 throw 'Could not un-gzip (exit code ${result.exitCode}). Error:\n'
798 '${Strings.join(result.stdout, "\n")}\n'
799 '${Strings.join(result.stderr, "\n")}';
800 }
801 // Find the tar file we just created since we don't know its name.
802 return listDir(tempDir);
803 }).then((files) {
804 var tarFile;
805 for (var file in files) {
806 if (path.extension(file) == '.tar') {
807 tarFile = file;
808 break;
809 } 817 }
810 } 818 return true;
811 819 });
812 if (tarFile == null) throw 'The gzip file did not contain a tar file.'; 820 });
813
814 // Untar the archive into the destination directory.
815 return runProcess(command, ['x', tarFile], workingDir: destination);
816 }).then((result) {
817 if (result.exitCode != 0) {
818 throw 'Could not un-tar (exit code ${result.exitCode}). Error:\n'
819 '${Strings.join(result.stdout, "\n")}\n'
820 '${Strings.join(result.stderr, "\n")}';
821 }
822
823 log.fine('Clean up 7zip temp directory ${tempDir.path}.');
824 // TODO(rnystrom): Should also delete this if anything fails.
825 return deleteDir(tempDir);
826 }).then((_) => true);
827 } 821 }
828 822
829 /// Create a .tar.gz archive from a list of entries. Each entry can be a 823 /// Create a .tar.gz archive from a list of entries. Each entry can be a
830 /// [String], [Directory], or [File] object. The root of the archive is 824 /// [String], [Directory], or [File] object. The root of the archive is
831 /// considered to be [baseDir], which defaults to the current working directory. 825 /// considered to be [baseDir], which defaults to the current working directory.
832 /// Returns a [ByteStream] that will emit the contents of the archive. 826 /// Returns a [ByteStream] that will emit the contents of the archive.
833 ByteStream createTarGz(List contents, {baseDir}) { 827 ByteStream createTarGz(List contents, {baseDir}) {
834 var buffer = new StringBuffer(); 828 var buffer = new StringBuffer();
835 buffer.add('Creating .tag.gz stream containing:\n'); 829 buffer.add('Creating .tag.gz stream containing:\n');
836 contents.forEach((file) => buffer.add('$file\n')); 830 contents.forEach((file) => buffer.add('$file\n'));
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 Directory _getDirectory(entry) { 941 Directory _getDirectory(entry) {
948 if (entry is Directory) return entry; 942 if (entry is Directory) return entry;
949 return new Directory(entry); 943 return new Directory(entry);
950 } 944 }
951 945
952 /// Gets a [Uri] for [uri], which can either already be one, or be a [String]. 946 /// Gets a [Uri] for [uri], which can either already be one, or be a [String].
953 Uri _getUri(uri) { 947 Uri _getUri(uri) {
954 if (uri is Uri) return uri; 948 if (uri is Uri) return uri;
955 return Uri.parse(uri); 949 return Uri.parse(uri);
956 } 950 }
OLDNEW
« no previous file with comments | « utils/pub/hosted_source.dart ('k') | utils/pub/system_cache.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698