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