Index: utils/pub/io.dart |
diff --git a/utils/pub/io.dart b/utils/pub/io.dart |
index c4f5edfa31c478a7bb09dc05b09c127974217a01..85a094cedab2953ab3cf2b0f9da8bf22fe1d5e21 100644 |
--- a/utils/pub/io.dart |
+++ b/utils/pub/io.dart |
@@ -22,17 +22,6 @@ export '../../pkg/http/lib/http.dart' show ByteStream; |
final NEWLINE_PATTERN = new RegExp("\r\n?|\n\r?"); |
-/// Joins a number of path string parts into a single path. Handles |
-/// platform-specific path separators. Parts can be [String], [Directory], or |
-/// [File] objects. |
-String join(part1, [part2, part3, part4, part5, part6, part7, part8]) { |
- var parts = [part1, part2, part3, part4, part5, part6, part7, part8] |
- .map((part) => part == null ? null : _getPath(part)).toList(); |
- |
- return path.join(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], |
- parts[6], parts[7]); |
-} |
- |
/// Returns whether or not [entry] is nested somewhere within [dir]. This just |
/// performs a path comparison; it doesn't look at the actual filesystem. |
bool isBeneath(String entry, String dir) { |
@@ -40,92 +29,82 @@ bool isBeneath(String entry, String dir) { |
return !path.isAbsolute(relative) && path.split(relative)[0] != '..'; |
} |
-/// Determines if [path], which can be a [String] file path, a [File], or a |
-/// [Directory] exists on the file system. |
-bool entryExists(path) => fileExists(path) || dirExists(path); |
+/// Determines if a file or directory at [path] exists. |
+bool entryExists(String path) => fileExists(path) || dirExists(path); |
-/// Determines if [file], which can be a [String] file path or a [File], exists |
-/// on the file system. |
-bool fileExists(file) => _getFile(file).existsSync(); |
+/// Determines if [file] exists on the file system. |
+bool fileExists(String file) => new File(file).existsSync(); |
-/// Reads the contents of the text file [file], which can either be a [String] |
-/// or a [File]. |
-String readTextFile(file) => _getFile(file).readAsStringSync(Encoding.UTF_8); |
+/// Reads the contents of the text file [file]. |
+String readTextFile(String file) => |
+ new File(file).readAsStringSync(Encoding.UTF_8); |
-/// Reads the contents of the binary file [file], which can either be a [String] |
-/// or a [File]. |
-List<int> readBinaryFile(file) { |
- var path = _getPath(file); |
- log.io("Reading binary file $path."); |
- var contents = new File(path).readAsBytesSync(); |
- log.io("Read ${contents.length} bytes from $path."); |
+/// Reads the contents of the binary file [file]. |
+List<int> readBinaryFile(String file) { |
+ log.io("Reading binary file $file."); |
+ var contents = new File(file).readAsBytesSync(); |
+ log.io("Read ${contents.length} bytes from $file."); |
return contents; |
} |
-/// Creates [file] (which can either be a [String] or a [File]), and writes |
-/// [contents] to it. |
+/// Creates [file] and writes [contents] to it. |
/// |
/// If [dontLogContents] is true, the contents of the file will never be logged. |
-File writeTextFile(file, String contents, {dontLogContents: false}) { |
- var path = _getPath(file); |
- file = new File(path); |
- |
+String writeTextFile(String file, String contents, {dontLogContents: false}) { |
// Sanity check: don't spew a huge file. |
- log.io("Writing ${contents.length} characters to text file $path."); |
+ log.io("Writing ${contents.length} characters to text file $file."); |
if (!dontLogContents && contents.length < 1024 * 1024) { |
log.fine("Contents:\n$contents"); |
} |
- return file..writeAsStringSync(contents); |
+ new File(file).writeAsStringSync(contents); |
+ return file; |
} |
-/// Deletes [file], which can be a [String] or a [File]. |
-File deleteFile(file) => _getFile(file)..delete(); |
- |
-/// Creates [file] (which can either be a [String] or a [File]), and writes |
-/// [contents] to it. |
-File writeBinaryFile(file, List<int> contents) { |
- var path = _getPath(file); |
- file = new File(path); |
+/// Deletes [file]. |
+void deleteFile(String file) { |
+ new File(file).delete(); |
+} |
- log.io("Writing ${contents.length} bytes to binary file $path."); |
- file.openSync(FileMode.WRITE) |
+/// Creates [file] and writes [contents] to it. |
+String writeBinaryFile(String file, List<int> contents) { |
+ log.io("Writing ${contents.length} bytes to binary file $file."); |
+ new File(file).openSync(FileMode.WRITE) |
..writeListSync(contents, 0, contents.length) |
..closeSync(); |
- log.fine("Wrote text file $path."); |
+ log.fine("Wrote text file $file."); |
return file; |
} |
-/// 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(Stream<List<int>> stream, path) { |
- path = _getPath(path); |
- |
- log.io("Creating $path from stream."); |
+/// Writes [stream] to a new file at path [file]. Will replace any file already |
+/// at that path. Completes when the file is done being written. |
+Future<String> createFileFromStream(Stream<List<int>> stream, String file) { |
+ log.io("Creating $file from stream."); |
- var file = new File(path); |
- return stream.pipe(wrapOutputStream(file.openOutputStream())).then((_) { |
- log.fine("Created $path from stream."); |
+ var stream = new File(file).openOutputStream(); |
+ return stream.pipe(wrapOutputStream(stream)).then((_) { |
+ log.fine("Created $file from stream."); |
+ return file; |
}); |
} |
/// Creates a directory [dir]. |
-Directory createDir(dir) => _getDirectory(dir)..createSync(); |
+String createDir(String dir) { |
+ new Directory(dir).createSync(); |
+ return dir; |
+} |
/// Ensures that [dirPath] and all its parent directories exist. If they don't |
/// exist, creates them. |
-Directory ensureDir(dirPath) { |
- dirPath = _getPath(dirPath); |
- |
+String ensureDir(String dirPath) { |
log.fine("Ensuring directory $dirPath exists."); |
var dir = new Directory(dirPath); |
- if (dirPath == '.' || dirExists(dirPath)) return dir; |
+ if (dirPath == '.' || dirExists(dirPath)) return dirPath; |
ensureDir(path.dirname(dirPath)); |
try { |
- createDir(dir); |
+ createDir(dirPath); |
} on DirectoryIOException catch (ex) { |
// Error 17 means the directory already exists (or 183 on Windows). |
if (ex.osError.errorCode == 17 || ex.osError.errorCode == 183) { |
@@ -135,7 +114,7 @@ Directory ensureDir(dirPath) { |
} |
} |
- return dir; |
+ return dirPath; |
} |
/// Creates a temp directory whose name will be based on [dir] with a unique |
@@ -143,35 +122,32 @@ Directory ensureDir(dirPath) { |
/// created in a platform-dependent temporary location. Returns the path of the |
/// created directory. |
String createTempDir([dir = '']) { |
- var tempDir = _getDirectory(dir).createTempSync(); |
+ var tempDir = new Directory(dir).createTempSync(); |
log.io("Created temp directory ${tempDir.path}"); |
return tempDir.path; |
} |
-/// Asynchronously recursively deletes [dir], which can be a [String] or a |
-/// [Directory]. Returns a [Future] that completes when the deletion is done. |
-Future<Directory> deleteDir(dir) { |
- dir = _getDirectory(dir); |
- |
- return _attemptRetryable(() => log.ioAsync("delete directory ${dir.path}", |
- dir.delete(recursive: true))); |
+/// Asynchronously recursively deletes [dir]. Returns a [Future] that completes |
+/// when the deletion is done. |
+Future<String> deleteDir(String dir) { |
+ return _attemptRetryable(() => log.ioAsync("delete directory $dir", |
+ new Directory(dir).delete(recursive: true).then((_) => dir))); |
} |
-/// Asynchronously lists the contents of [dir], which can be a [String] |
-/// directory path or a [Directory]. If [recursive] is `true`, lists |
+/// Asynchronously lists the contents of [dir]. If [recursive] is `true`, lists |
/// subdirectory contents (defaults to `false`). If [includeHiddenFiles] is |
/// `true`, includes files and directories beginning with `.` (defaults to |
/// `false`). |
/// |
/// If [dir] is a string, the returned paths are guaranteed to begin with it. |
-Future<List<String>> listDir(dir, |
+Future<List<String>> listDir(String dir, |
{bool recursive: false, bool includeHiddenFiles: false}) { |
- Future<List<String>> doList(Directory dir, Set<String> listedDirectories) { |
+ Future<List<String>> doList(String dir, Set<String> listedDirectories) { |
var contents = <String>[]; |
var completer = new Completer<List<String>>(); |
// Avoid recursive symlinks. |
- var resolvedPath = new File(dir.path).fullPathSync(); |
+ var resolvedPath = new File(dir).fullPathSync(); |
if (listedDirectories.contains(resolvedPath)) { |
return new Future.immediate([]); |
} |
@@ -179,15 +155,14 @@ Future<List<String>> listDir(dir, |
listedDirectories = new Set<String>.from(listedDirectories); |
listedDirectories.add(resolvedPath); |
- log.io("Listing directory ${dir.path}."); |
- var lister = dir.list(); |
+ log.io("Listing directory $dir."); |
+ var lister = new Directory(dir).list(); |
lister.onDone = (done) { |
// TODO(rnystrom): May need to sort here if it turns out onDir and onFile |
// aren't guaranteed to be called in a certain order. So far, they seem to. |
if (done) { |
- log.fine("Listed directory ${dir.path}:\n" |
- "${contents.join('\n')}"); |
+ log.fine("Listed directory $dir:\n${contents.join('\n')}"); |
completer.complete(contents); |
} |
}; |
@@ -204,19 +179,19 @@ Future<List<String>> listDir(dir, |
lister.onError = (error) => completer.completeError(error, stackTrace); |
lister.onDir = (file) { |
if (!includeHiddenFiles && path.basename(file).startsWith('.')) return; |
- file = join(dir, path.basename(file)); |
+ file = path.join(dir, path.basename(file)); |
contents.add(file); |
// TODO(nweiz): don't manually recurse once issue 7358 is fixed. Note that |
// once we remove the manual recursion, we'll need to explicitly filter |
// out files in hidden directories. |
if (recursive) { |
- children.add(doList(new Directory(file), listedDirectories)); |
+ children.add(doList(file, listedDirectories)); |
} |
}; |
lister.onFile = (file) { |
if (!includeHiddenFiles && path.basename(file).startsWith('.')) return; |
- contents.add(join(dir, path.basename(file))); |
+ contents.add(path.join(dir, path.basename(file))); |
}; |
return completer.future.then((contents) { |
@@ -227,17 +202,16 @@ Future<List<String>> listDir(dir, |
}); |
} |
- return doList(_getDirectory(dir), new Set<String>()); |
+ return doList(dir, new Set<String>()); |
} |
-/// Determines if [dir], which can be a [String] directory path or a |
-/// [Directory], exists on the file system. |
-bool dirExists(dir) => _getDirectory(dir).existsSync(); |
+/// Determines if [dir] exists on the file system. |
+bool dirExists(String dir) => new Directory(dir).existsSync(); |
/// "Cleans" [dir]. If that directory already exists, it will be deleted. Then a |
/// new empty directory will be created. Returns a [Future] that completes when |
/// the new clean directory is created. |
-Future<Directory> cleanDir(dir) { |
+Future<String> cleanDir(String dir) { |
return defer(() { |
if (dirExists(dir)) { |
// Delete it first. |
@@ -251,13 +225,12 @@ Future<Directory> cleanDir(dir) { |
/// Renames (i.e. moves) the directory [from] to [to]. Returns a [Future] with |
/// the destination directory. |
-Future<Directory> renameDir(from, String to) { |
- from = _getDirectory(from); |
- log.io("Renaming directory ${from.path} to $to."); |
+Future<String> renameDir(String from, String to) { |
+ log.io("Renaming directory $from to $to."); |
- return _attemptRetryable(() => from.rename(to)).then((dir) { |
- log.fine("Renamed directory ${from.path} to $to."); |
- return dir; |
+ return _attemptRetryable(() => new Directory(from).rename(to)).then((dir) { |
+ log.fine("Renamed directory $from to $to."); |
+ return to; |
}); |
} |
@@ -291,15 +264,11 @@ Future _attemptRetryable(Future callback()) { |
return makeAttempt(null); |
} |
-/// Creates a new symlink that creates an alias from [from] to [to], both of |
-/// which can be a [String], [File], or [Directory]. Returns a [Future] which |
-/// completes to the symlink file (i.e. [to]). |
+/// Creates a new symlink that creates an alias from [from] to [to]. Returns a |
+/// [Future] which completes to the symlink file (i.e. [to]). |
/// |
/// Note that on Windows, only directories may be symlinked to. |
-Future<File> createSymlink(from, to) { |
- from = _getPath(from); |
- to = _getPath(to); |
- |
+Future<String> createSymlink(String from, String to) { |
log.fine("Creating symlink ($to is a symlink to $from)"); |
var command = 'ln'; |
@@ -315,22 +284,19 @@ Future<File> createSymlink(from, to) { |
args = ['/j', to, from]; |
} |
- return runProcess(command, args).then((result) { |
- // TODO(rnystrom): Check exit code and output? |
- return new File(to); |
- }); |
+ // TODO(rnystrom): Check exit code and output? |
+ return runProcess(command, args).then((result) => to); |
} |
/// Creates a new symlink that creates an alias from the `lib` directory of |
-/// package [from] to [to], both of which can be a [String], [File], or |
-/// [Directory]. Returns a [Future] which completes to the symlink file (i.e. |
-/// [to]). If [from] does not have a `lib` directory, this shows a warning if |
-/// appropriate and then does nothing. |
-Future<File> createPackageSymlink(String name, from, to, |
+/// package [from] to [to]. Returns a [Future] which completes to the symlink |
+/// file (i.e. [to]). If [from] does not have a `lib` directory, this shows a |
+/// warning if appropriate and then does nothing. |
+Future<String> createPackageSymlink(String name, String from, String to, |
{bool isSelfLink: false}) { |
return defer(() { |
// See if the package has a "lib" directory. |
- from = join(from, 'lib'); |
+ from = path.join(from, 'lib'); |
log.fine("Creating ${isSelfLink ? "self" : ""}link for package '$name'."); |
if (dirExists(from)) return createSymlink(from, to); |
@@ -342,7 +308,7 @@ Future<File> createPackageSymlink(String name, from, to, |
'you will not be able to import any libraries from it.'); |
} |
- return _getFile(to); |
+ return to; |
}); |
} |
@@ -360,7 +326,7 @@ String relativeToPub(String target) { |
utilDir = path.dirname(utilDir); |
} |
- return path.normalize(join(utilDir, 'pub', target)); |
+ return path.normalize(path.join(utilDir, 'pub', target)); |
} |
// TODO(nweiz): add a ByteSink wrapper to make writing strings to stdout/stderr |
@@ -643,8 +609,8 @@ class PubProcess { |
/// Calls [fn] with appropriately modified arguments. [fn] should have the same |
/// signature as [Process.start], except that the returned [Future] may have a |
/// type other than [Process]. |
-Future _doProcess(Function fn, String executable, List<String> args, workingDir, |
- Map<String, String> environment) { |
+Future _doProcess(Function fn, String executable, List<String> args, |
+ String workingDir, Map<String, String> environment) { |
// 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 |
@@ -657,7 +623,7 @@ Future _doProcess(Function fn, String executable, List<String> args, workingDir, |
final options = new ProcessOptions(); |
if (workingDir != null) { |
- options.workingDirectory = _getDirectory(workingDir).path; |
+ options.workingDirectory = workingDir; |
} |
if (environment != null) { |
@@ -713,11 +679,9 @@ Future withTempDir(Future fn(String path)) { |
}); |
} |
-/// Extracts a `.tar.gz` file from [stream] to [destination], which can be a |
-/// directory or a path. Returns whether or not the extraction was successful. |
-Future<bool> extractTarGz(Stream<List<int>> stream, destination) { |
- destination = _getPath(destination); |
- |
+/// Extracts a `.tar.gz` file from [stream] to [destination]. Returns whether |
+/// or not the extraction was successful. |
+Future<bool> extractTarGz(Stream<List<int>> stream, String destination) { |
log.fine("Extracting .tar.gz stream to $destination."); |
if (Platform.operatingSystem == "windows") { |
@@ -761,7 +725,8 @@ Future<bool> _extractTarGzWindows(Stream<List<int>> stream, |
return withTempDir((tempDir) { |
// Write the archive to a temp file. |
- return createFileFromStream(stream, join(tempDir, 'data.tar.gz')).then((_) { |
+ var dataFile = path.join(tempDir, 'data.tar.gz'); |
+ return createFileFromStream(stream, dataFile).then((_) { |
// 7zip can't unarchive from gzip -> tar -> destination all in one step |
// first we un-gzip it to a tar file. |
// Note: Setting the working directory instead of passing in a full file |
@@ -816,7 +781,7 @@ ByteStream createTarGz(List contents, {baseDir}) { |
if (baseDir == null) baseDir = path.current; |
baseDir = path.absolute(baseDir); |
contents = contents.map((entry) { |
- entry = path.absolute(_getPath(entry)); |
+ entry = path.absolute(entry); |
if (!isBeneath(entry, baseDir)) { |
throw 'Entry $entry is not inside $baseDir.'; |
} |
@@ -825,7 +790,7 @@ ByteStream createTarGz(List contents, {baseDir}) { |
if (Platform.operatingSystem != "windows") { |
var args = ["--create", "--gzip", "--directory", baseDir]; |
- args.addAll(contents.map(_getPath)); |
+ args.addAll(contents); |
// TODO(nweiz): It's possible that enough command-line arguments will make |
// the process choke, so at some point we should save the arguments to a |
// file and pass them in via --files-from for tar and -i@filename for 7zip. |
@@ -842,7 +807,7 @@ ByteStream createTarGz(List contents, {baseDir}) { |
withTempDir((tempDir) { |
// Create the tar file. |
- var tarFile = join(tempDir, "intermediate.tar"); |
+ var tarFile = path.join(tempDir, "intermediate.tar"); |
var args = ["a", "-w$baseDir", tarFile]; |
args.addAll(contents.map((entry) => '-i!"$entry"')); |
@@ -897,31 +862,6 @@ class PubProcessResult { |
bool get success => exitCode == 0; |
} |
-/// Gets a dart:io [File] for [entry], which can either already be a File or be |
-/// a path string. |
-File _getFile(entry) { |
- if (entry is File) return entry; |
- if (entry is String) return new File(entry); |
- throw 'Entry $entry is not a supported type.'; |
-} |
- |
-/// Gets the path string for [entry], which can either already be a path string, |
-/// or be a [File] or [Directory]. Allows working generically with "file-like" |
-/// objects. |
-String _getPath(entry) { |
- if (entry is String) return entry; |
- if (entry is File) return entry.name; |
- if (entry is Directory) return entry.path; |
- throw 'Entry $entry is not a supported type.'; |
-} |
- |
-/// Gets a [Directory] for [entry], which can either already be one, or be a |
-/// [String]. |
-Directory _getDirectory(entry) { |
- if (entry is Directory) return entry; |
- return new Directory(entry); |
-} |
- |
/// Gets a [Uri] for [uri], which can either already be one, or be a [String]. |
Uri _getUri(uri) { |
if (uri is Uri) return uri; |