| 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 library source; | 5 library source; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'io.dart'; | 8 import 'io.dart'; |
| 9 import 'package.dart'; | 9 import 'package.dart'; |
| 10 import 'pubspec.dart'; | 10 import 'pubspec.dart'; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 } | 101 } |
| 102 | 102 |
| 103 /// Installs the package identified by [id] to the system cache. This is only | 103 /// Installs the package identified by [id] to the system cache. This is only |
| 104 /// called for sources with [shouldCache] set to true. | 104 /// called for sources with [shouldCache] set to true. |
| 105 /// | 105 /// |
| 106 /// By default, this uses [systemCacheDirectory] and [install]. | 106 /// By default, this uses [systemCacheDirectory] and [install]. |
| 107 Future<Package> installToSystemCache(PackageId id) { | 107 Future<Package> installToSystemCache(PackageId id) { |
| 108 var path; | 108 var path; |
| 109 return systemCacheDirectory(id).then((p) { | 109 return systemCacheDirectory(id).then((p) { |
| 110 path = p; | 110 path = p; |
| 111 if (dirExists(path)) return true; | 111 |
| 112 // See if it's already cached. |
| 113 if (!dirExists(path)) return false; |
| 114 |
| 115 return _isCachedPackageCorrupted(path).then((isCorrupted) { |
| 116 if (!isCorrupted) return true; |
| 117 |
| 118 // Busted, so wipe out the package and reinstall. |
| 119 return deleteDir(path).then((_) => false); |
| 120 }); |
| 121 }).then((isInstalled) { |
| 122 if (isInstalled) return true; |
| 112 ensureDir(dirname(path)); | 123 ensureDir(dirname(path)); |
| 113 return install(id, path); | 124 return install(id, path); |
| 114 }).then((found) { | 125 }).then((found) { |
| 115 if (!found) throw 'Package $id not found.'; | 126 if (!found) throw 'Package $id not found.'; |
| 116 return new Package.load(id.name, path, systemCache.sources); | 127 return new Package.load(id.name, path, systemCache.sources); |
| 117 }); | 128 }); |
| 118 } | 129 } |
| 119 | 130 |
| 131 /// Since pub generates symlinks that point into the system cache (in |
| 132 /// particular, targeting the "lib" directories of cached packages), it's |
| 133 /// possible to accidentally break cached packages if something traverses |
| 134 /// that symlink. |
| 135 /// |
| 136 /// This tries to determine if the cached package at [packageDir] has been |
| 137 /// corrupted. The heuristics are it is corrupted if any of the following are |
| 138 /// true: |
| 139 /// |
| 140 /// * It has an empty "lib" directory. |
| 141 /// * It has no pubspec. |
| 142 Future<bool> _isCachedPackageCorrupted(String packageDir) { |
| 143 return defer(() { |
| 144 if (!fileExists(join(packageDir, "pubspec.yaml"))) return true; |
| 145 |
| 146 var libDir = join(packageDir, "lib"); |
| 147 if (dirExists(libDir)) { |
| 148 return listDir(libDir).then((contents) => contents.length == 0); |
| 149 } |
| 150 |
| 151 // If we got here, it's OK. |
| 152 return false; |
| 153 }); |
| 154 } |
| 155 |
| 120 /// Returns the directory in the system cache that the package identified by | 156 /// Returns the directory in the system cache that the package identified by |
| 121 /// [id] should be installed to. This should return a path to a subdirectory | 157 /// [id] should be installed to. This should return a path to a subdirectory |
| 122 /// of [systemCacheRoot]. | 158 /// of [systemCacheRoot]. |
| 123 /// | 159 /// |
| 124 /// This doesn't need to be implemented if [shouldCache] is false. | 160 /// This doesn't need to be implemented if [shouldCache] is false. |
| 125 Future<String> systemCacheDirectory(PackageId id) { | 161 Future<String> systemCacheDirectory(PackageId id) { |
| 126 return new Future.immediateError( | 162 return new Future.immediateError( |
| 127 "systemCacheDirectory() must be implemented if shouldCache is true."); | 163 "systemCacheDirectory() must be implemented if shouldCache is true."); |
| 128 } | 164 } |
| 129 | 165 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 /// according to [validateDescription], although it must still be serializable | 199 /// according to [validateDescription], although it must still be serializable |
| 164 /// to JSON and YAML. It must also be equal to [id] according to | 200 /// to JSON and YAML. It must also be equal to [id] according to |
| 165 /// [descriptionsEqual]. | 201 /// [descriptionsEqual]. |
| 166 /// | 202 /// |
| 167 /// By default, this just returns [id]. | 203 /// By default, this just returns [id]. |
| 168 Future<PackageId> resolveId(PackageId id) => new Future.immediate(id); | 204 Future<PackageId> resolveId(PackageId id) => new Future.immediate(id); |
| 169 | 205 |
| 170 /// Returns the source's name. | 206 /// Returns the source's name. |
| 171 String toString() => name; | 207 String toString() => name; |
| 172 } | 208 } |
| OLD | NEW |