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