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

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

Issue 10214006: Refactor command code and add support for --help and --version. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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
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 /** 5 /**
6 * Helper functionality to make working with IO easier. 6 * Helper functionality to make working with IO easier.
7 */ 7 */
8 #library('pub_io'); 8 #library('pub_io');
9 9
10 #import('dart:io'); 10 #import('dart:io');
11 11
12 #import('../lib/file_system.dart', prefix: 'fs'); 12 #import('../lib/file_system.dart', prefix: 'fs');
13 13
14 /** Gets the current working directory. */
15 String get workingDir() => new File('.').fullPathSync();
16
14 /** 17 /**
15 * Joins a number of path string parts into a single path. Handles 18 * Joins a number of path string parts into a single path. Handles
16 * platform-specific path separators. Parts can be [String], [Directory], or 19 * platform-specific path separators. Parts can be [String], [Directory], or
17 * [File] objects. 20 * [File] objects.
18 */ 21 */
19 String join(part1, [part2, part3, part4]) { 22 String join(part1, [part2, part3, part4]) {
20 final parts = _getPath(part1).split('/'); 23 final parts = _getPath(part1).split('/');
21 24
22 for (final part in [part2, part3, part4]) { 25 for (final part in [part2, part3, part4]) {
23 if (part == null) continue; 26 if (part == null) continue;
(...skipping 16 matching lines...) Expand all
40 43
41 /** 44 /**
42 * Gets the basename, the file name without any leading directory path, for 45 * Gets the basename, the file name without any leading directory path, for
43 * [file], which can either be a [String], [File], or [Directory]. 46 * [file], which can either be a [String], [File], or [Directory].
44 */ 47 */
45 String basename(file) { 48 String basename(file) {
46 return fs.basename(_getPath(file)); 49 return fs.basename(_getPath(file));
47 } 50 }
48 51
49 /** 52 /**
53 * Asynchronously determines if [file], which can be a [String] file path or a
54 * [File], exists on the file system. Returns a [Future] that completes with
55 * the result.
56 */
57 Future<bool> fileExists(file) {
58 final completer = new Completer<bool>();
59
60 file = new File(_getPath(file));
61 file.onError = (error) => completer.completeException(error);
62 file.exists((exists) => completer.complete(exists));
63
64 return completer.future;
65 }
66
67 /**
50 * Reads the contents of the text file [file], which can either be a [String] or 68 * Reads the contents of the text file [file], which can either be a [String] or
51 * a [File]. 69 * a [File].
52 */ 70 */
53 Future<String> readTextFile(file) { 71 Future<String> readTextFile(file) {
54 file = new File(_getPath(file)); 72 file = new File(_getPath(file));
55 final completer = new Completer<String>(); 73 final completer = new Completer<String>();
56 file.onError = (error) => completer.completeException(error); 74 file.onError = (error) => completer.completeException(error);
57 file.readAsText(Encoding.UTF_8, (text) => completer.complete(text)); 75 file.readAsText(Encoding.UTF_8, (text) => completer.complete(text));
58 76
59 return completer.future; 77 return completer.future;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 dir.createTemp(() => completer.complete(dir)); 121 dir.createTemp(() => completer.complete(dir));
104 122
105 return completer.future; 123 return completer.future;
106 } 124 }
107 125
108 /** 126 /**
109 * Asynchronously recursively deletes [dir], which can be a [String] or a 127 * Asynchronously recursively deletes [dir], which can be a [String] or a
110 * [Directory]. Returns a [Future] that completes when the deletion is done. 128 * [Directory]. Returns a [Future] that completes when the deletion is done.
111 */ 129 */
112 Future<Directory> deleteDir(dir) { 130 Future<Directory> deleteDir(dir) {
131 // TODO(rnystrom): Hack! Temporary! Right now, dart:io's Directory delete
132 // method can't handle directories with symlinks, which is exactly what pub
133 // creates and deletes. Instead, we'll just shell out to 'rm'. Remove this
134 // when dartbug.com/2646 is fixed.
135 dir = _getDirectory(dir);
136
137 // Sanity check!
138 if (dir.path == '/' ||
139 dir.path == '.' ||
140 dir.path == '..' ||
141 dir.path == '~' ||
142 dir.path == '*') throw "(O.o) I don't think you want to do that!";
143
144 return runProcess('rm', ['-rf', dir.path]).transform((result) => dir);
145 // End hack!
146
147 // Real code:
148 /*
113 final completer = new Completer<Directory>(); 149 final completer = new Completer<Directory>();
114 dir = _getDirectory(dir); 150 dir = _getDirectory(dir);
115 dir.onError = (error) => completer.completeException(error); 151 dir.onError = (error) => completer.completeException(error);
116 dir.deleteRecursively(() => completer.complete(dir)); 152 dir.deleteRecursively(() => completer.complete(dir));
117 153
118 return completer.future; 154 return completer.future;
155 */
119 } 156 }
120 157
121 /** 158 /**
122 * Asynchronously lists the contents of [dir], which can be a [String] directory 159 * Asynchronously lists the contents of [dir], which can be a [String] directory
123 * path or a [Directory]. If [recursive] is `true`, lists subdirectory contents 160 * path or a [Directory]. If [recursive] is `true`, lists subdirectory contents
124 * (defaults to `false`). If [includeSpecialFiles] is `true`, includes 161 * (defaults to `false`). If [includeSpecialFiles] is `true`, includes
125 * hidden `.DS_Store` files (defaults to `false`, other hidden files may be 162 * hidden `.DS_Store` files (defaults to `false`, other hidden files may be
126 * omitted later). 163 * omitted later).
127 */ 164 */
128 Future<List<String>> listDir(dir, 165 Future<List<String>> listDir(dir,
(...skipping 17 matching lines...) Expand all
146 } 183 }
147 contents.add(file); 184 contents.add(file);
148 }; 185 };
149 186
150 dir.list(recursive: recursive); 187 dir.list(recursive: recursive);
151 188
152 return completer.future; 189 return completer.future;
153 } 190 }
154 191
155 /** 192 /**
193 * Asynchronously determines if [dir], which can be a [String] directory path
194 * or a [Directory], exists on the file system. Returns a [Future] that
195 * completes with the result.
196 */
197 Future<bool> dirExists(dir) {
198 final completer = new Completer<bool>();
199
200 dir = _getDirectory(dir);
201 dir.onError = (error) => completer.completeException(error);
202 dir.exists((exists) => completer.complete(exists));
203
204 return completer.future;
205 }
206
207 /**
208 * "Cleans" [dir]. If that directory already exists, it will be deleted. Then a
209 * new empty directory will be created. Returns a [Future] that completes when
210 * the new clean directory is created.
211 */
212 Future<Directory> cleanDir(dir) {
213 return dirExists(dir).chain((exists) {
214 if (exists) {
215 // Delete it first.
216 return deleteDir(dir).chain((_) => createDir(dir));
217 } else {
218 // Just create it.
219 return createDir(dir);
220 }
221 });
222 }
223
224 /**
225 * Creates a new symlink that creates an alias from [from] to [to], both of
226 * which can be a [String], [File], or [Directory]. Returns a [Future] which
227 * completes to the symlink file (i.e. [to]).
228 */
229 Future<File> createSymlink(from, to) {
230 // TODO(rnystrom): What should this do on Windows?
231 from = _getPath(from);
232 to = _getPath(to);
233
234 return runProcess('ln', ['-s', from, to]).transform((result) {
235 // TODO(rnystrom): Check exit code and output?
236 return new File(to);
237 });
238 }
239
240 /**
241 * Given [entry] which may be a [String], [File], or [Directory] relative to
242 * the current working directory, returns its full canonicalized path.
243 */
244 // TODO(rnystrom): Should this be async?
245 String getFullPath(entry) => new File(_getPath(entry)).fullPathSync();
246
247 /**
156 * Spawns and runs the process located at [executable], passing in [args]. 248 * Spawns and runs the process located at [executable], passing in [args].
157 * Returns a [Future] that will complete the results of the process after it 249 * Returns a [Future] that will complete the results of the process after it
158 * has ended. 250 * has ended.
159 */ 251 */
160 Future<ProcessResult> runProcess(String executable, List<String> args) { 252 Future<ProcessResult> runProcess(String executable, List<String> args,
253 [String workingDir]) {
161 int exitCode; 254 int exitCode;
162 255
163 final process = new Process.start(executable, args); 256 final options = new ProcessOptions();
257 if (workingDir != null) options.workingDirectory = workingDir;
258
259 final process = new Process.start(executable, args, options);
164 260
165 final outStream = new StringInputStream(process.stdout); 261 final outStream = new StringInputStream(process.stdout);
166 final processStdout = <String>[]; 262 final processStdout = <String>[];
167 263
168 final errStream = new StringInputStream(process.stderr); 264 final errStream = new StringInputStream(process.stderr);
169 final processStderr = <String>[]; 265 final processStderr = <String>[];
170 266
171 final completer = new Completer<ProcessResult>(); 267 final completer = new Completer<ProcessResult>();
172 268
173 checkComplete() { 269 checkComplete() {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 } 318 }
223 319
224 /** 320 /**
225 * Gets a [Directory] for [entry], which can either already be one, or be a 321 * Gets a [Directory] for [entry], which can either already be one, or be a
226 * [String]. 322 * [String].
227 */ 323 */
228 Directory _getDirectory(entry) { 324 Directory _getDirectory(entry) {
229 if (entry is Directory) return entry; 325 if (entry is Directory) return entry;
230 return new Directory(entry); 326 return new Directory(entry);
231 } 327 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698