OLD | NEW |
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 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 | 257 |
258 // Wait a bit and try again. | 258 // Wait a bit and try again. |
259 log.fine("Operation failed, retrying (attempt $attempts)."); | 259 log.fine("Operation failed, retrying (attempt $attempts)."); |
260 return sleep(500).then(makeAttempt); | 260 return sleep(500).then(makeAttempt); |
261 }); | 261 }); |
262 } | 262 } |
263 | 263 |
264 return makeAttempt(null); | 264 return makeAttempt(null); |
265 } | 265 } |
266 | 266 |
267 /// Creates a new symlink that creates an alias from [from] to [to]. Returns a | 267 /// Creates a new symlink at path [symlink] that points to [target]. Returns a |
268 /// [Future] which completes to the symlink file (i.e. [to]). | 268 /// [Future] which completes to the path to the symlink file. |
| 269 /// |
| 270 /// If [relative] is true, creates a symlink with a relative path from the |
| 271 /// symlink to the target. Otherwise, uses the [target] path unmodified. |
269 /// | 272 /// |
270 /// Note that on Windows, only directories may be symlinked to. | 273 /// Note that on Windows, only directories may be symlinked to. |
271 Future<String> createSymlink(String from, String to) { | 274 Future<String> createSymlink(String target, String symlink, |
272 log.fine("Creating symlink ($to is a symlink to $from)"); | 275 {bool relative: false}) { |
| 276 if (relative) { |
| 277 // Relative junction points are not supported on Windows. Instead, just |
| 278 // make sure we have a clean absolute path because it will interpret a |
| 279 // relative path to be relative to the cwd, not the symlink, and will be |
| 280 // confused by forward slashes. |
| 281 if (Platform.operatingSystem == 'windows') { |
| 282 target = path.normalize(path.absolute(target)); |
| 283 } else { |
| 284 target = path.normalize( |
| 285 path.relative(target, from: path.dirname(symlink))); |
| 286 } |
| 287 } |
| 288 |
| 289 log.fine("Creating $symlink pointing to $target"); |
273 | 290 |
274 var command = 'ln'; | 291 var command = 'ln'; |
275 var args = ['-s', from, to]; | 292 var args = ['-s', target, symlink]; |
276 | 293 |
277 if (Platform.operatingSystem == 'windows') { | 294 if (Platform.operatingSystem == 'windows') { |
278 // Call mklink on Windows to create an NTFS junction point. Only works on | 295 // Call mklink on Windows to create an NTFS junction point. Only works on |
279 // Vista or later. (Junction points are available earlier, but the "mklink" | 296 // Vista or later. (Junction points are available earlier, but the "mklink" |
280 // command is not.) I'm using a junction point (/j) here instead of a soft | 297 // command is not.) I'm using a junction point (/j) here instead of a soft |
281 // link (/d) because the latter requires some privilege shenanigans that | 298 // link (/d) because the latter requires some privilege shenanigans that |
282 // I'm not sure how to specify from the command line. | 299 // I'm not sure how to specify from the command line. |
283 command = 'mklink'; | 300 command = 'mklink'; |
284 args = ['/j', to, from]; | 301 args = ['/j', symlink, target]; |
285 } | 302 } |
286 | 303 |
287 // TODO(rnystrom): Check exit code and output? | 304 // TODO(rnystrom): Check exit code and output? |
288 return runProcess(command, args).then((result) => to); | 305 return runProcess(command, args).then((result) => symlink); |
289 } | 306 } |
290 | 307 |
291 /// Creates a new symlink that creates an alias from the `lib` directory of | 308 /// Creates a new symlink that creates an alias at [symlink] that points to the |
292 /// package [from] to [to]. Returns a [Future] which completes to the symlink | 309 /// `lib` directory of package [target]. Returns a [Future] which completes to |
293 /// file (i.e. [to]). If [from] does not have a `lib` directory, this shows a | 310 /// the path to the symlink file. If [target] does not have a `lib` directory, |
294 /// warning if appropriate and then does nothing. | 311 /// this shows a warning if appropriate and then does nothing. |
295 Future<String> createPackageSymlink(String name, String from, String to, | 312 /// |
296 {bool isSelfLink: false}) { | 313 /// If [relative] is true, creates a symlink with a relative path from the |
| 314 /// symlink to the target. Otherwise, uses the [target] path unmodified. |
| 315 Future<String> createPackageSymlink(String name, String target, String symlink, |
| 316 {bool isSelfLink: false, bool relative: false}) { |
297 return defer(() { | 317 return defer(() { |
298 // See if the package has a "lib" directory. | 318 // See if the package has a "lib" directory. |
299 from = path.join(from, 'lib'); | 319 target = path.join(target, 'lib'); |
300 log.fine("Creating ${isSelfLink ? "self" : ""}link for package '$name'."); | 320 log.fine("Creating ${isSelfLink ? "self" : ""}link for package '$name'."); |
301 if (dirExists(from)) return createSymlink(from, to); | 321 if (dirExists(target)) { |
| 322 return createSymlink(target, symlink, relative: relative); |
| 323 } |
302 | 324 |
303 // It's OK for the self link (i.e. the root package) to not have a lib | 325 // It's OK for the self link (i.e. the root package) to not have a lib |
304 // directory since it may just be a leaf application that only has | 326 // directory since it may just be a leaf application that only has |
305 // code in bin or web. | 327 // code in bin or web. |
306 if (!isSelfLink) { | 328 if (!isSelfLink) { |
307 log.warning('Warning: Package "$name" does not have a "lib" directory so ' | 329 log.warning('Warning: Package "$name" does not have a "lib" directory so ' |
308 'you will not be able to import any libraries from it.'); | 330 'you will not be able to import any libraries from it.'); |
309 } | 331 } |
310 | 332 |
311 return to; | 333 return symlink; |
312 }); | 334 }); |
313 } | 335 } |
314 | 336 |
315 /// Resolves [target] relative to the location of pub.dart. | 337 /// Resolves [target] relative to the location of pub.dart. |
316 String relativeToPub(String target) { | 338 String relativeToPub(String target) { |
317 var scriptPath = new File(new Options().script).fullPathSync(); | 339 var scriptPath = new File(new Options().script).fullPathSync(); |
318 | 340 |
319 // Walk up until we hit the "util(s)" directory. This lets us figure out where | 341 // Walk up until we hit the "util(s)" directory. This lets us figure out where |
320 // we are if this function is called from pub.dart, or one of the tests, | 342 // we are if this function is called from pub.dart, or one of the tests, |
321 // which also live under "utils", or from the SDK where pub is in "util". | 343 // which also live under "utils", or from the SDK where pub is in "util". |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 const PubProcessResult(this.stdout, this.stderr, this.exitCode); | 882 const PubProcessResult(this.stdout, this.stderr, this.exitCode); |
861 | 883 |
862 bool get success => exitCode == 0; | 884 bool get success => exitCode == 0; |
863 } | 885 } |
864 | 886 |
865 /// Gets a [Uri] for [uri], which can either already be one, or be a [String]. | 887 /// Gets a [Uri] for [uri], which can either already be one, or be a [String]. |
866 Uri _getUri(uri) { | 888 Uri _getUri(uri) { |
867 if (uri is Uri) return uri; | 889 if (uri is Uri) return uri; |
868 return Uri.parse(uri); | 890 return Uri.parse(uri); |
869 } | 891 } |
OLD | NEW |