| 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('io.dart'); | 7 #import('io.dart'); |
| 8 #import('package.dart'); | 8 #import('package.dart'); |
| 9 #import('pubspec.dart'); | 9 #import('pubspec.dart'); |
| 10 #import('system_cache.dart'); | 10 #import('system_cache.dart'); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 | 113 |
| 114 /** | 114 /** |
| 115 * Installs the package identified by [id] to the system cache. This is only | 115 * Installs the package identified by [id] to the system cache. This is only |
| 116 * called for sources with [shouldCache] set to true. | 116 * called for sources with [shouldCache] set to true. |
| 117 * | 117 * |
| 118 * By default, this uses [systemCacheDirectory] and [install]. | 118 * By default, this uses [systemCacheDirectory] and [install]. |
| 119 */ | 119 */ |
| 120 Future<Package> installToSystemCache(PackageId id) { | 120 Future<Package> installToSystemCache(PackageId id) { |
| 121 var path = systemCacheDirectory(id); | 121 var path = systemCacheDirectory(id); |
| 122 return exists(path).chain((exists) { | 122 return exists(path).chain((exists) { |
| 123 if (exists) return new Future<bool>.immediate(true); | 123 // TODO(nweiz): better error handling |
| 124 return ensureDir(dirname(path)).chain((_) => install(id, path)); | 124 if (exists) throw 'Package $id is already installed.'; |
| 125 return ensureDir(dirname(path)); |
| 126 }).chain((_) { |
| 127 return install(id, path); |
| 125 }).chain((found) { | 128 }).chain((found) { |
| 126 if (!found) throw 'Package $id not found.'; | 129 if (!found) throw 'Package $id not found.'; |
| 127 return Package.load(path, systemCache.sources); | 130 return Package.load(path, systemCache.sources); |
| 128 }); | 131 }); |
| 129 } | 132 } |
| 130 | 133 |
| 131 /** | 134 /** |
| 132 * Returns the directory in the system cache that the package identified by | 135 * Returns the directory in the system cache that the package identified by |
| 133 * [id] should be installed to. This should return a path to a subdirectory of | 136 * [id] should be installed to. This should return a path to a subdirectory of |
| 134 * [systemCacheRoot]. | 137 * [systemCacheRoot]. |
| 135 * | 138 * |
| 136 * This doesn't need to be implemented if [shouldCache] is false, or if | 139 * This doesn't need to be implemented if [shouldCache] is false, or if |
| 137 * [installToSystemCache] is implemented. | 140 * [installToSystemCache] is implemented. |
| 138 */ | 141 */ |
| 139 String systemCacheDirectory(PackageId id) => | 142 String systemCacheDirectory(PackageId id) => |
| 140 join(systemCacheRoot, packageName(id.description)); | 143 join(systemCacheRoot, packageName(id.description)); |
| 141 | 144 |
| 142 /** | 145 /** |
| 143 * When a [Pubspec] or [LockFile] is parsed, it reads in the description for | 146 * When a [Pubspec] is parsed, it reads in the description for each |
| 144 * each dependency. It is up to the dependency's [Source] to determine how | 147 * dependency. It is up to the dependency's [Source] to determine how that |
| 145 * that should be interpreted. This will be called during parsing to validate | 148 * should be interpreted. This will be called during parsing to validate that |
| 146 * that the given [description] is well-formed according to this source. It | 149 * the given [description] is well-formed according to this source. It should |
| 147 * should return if the description is valid, or throw a [FormatException] if | 150 * return if the description is valid, or throw a [FormatException] if not. |
| 148 * not. | |
| 149 * | |
| 150 * [fromLockFile] is true when the description comes from a [LockFile], to | |
| 151 * allow the source to use lockfile-specific descriptions via [resolveId]. | |
| 152 */ | 151 */ |
| 153 void validateDescription(description, [bool fromLockFile=false]) {} | 152 void validateDescription(description) {} |
| 154 | 153 |
| 155 /** | 154 /** |
| 156 * Returns a human-friendly name for the package described by [description]. | 155 * Returns a human-friendly name for the package described by [description]. |
| 157 * This method should be light-weight. It doesn't need to validate that the | 156 * This method should be light-weight. It doesn't need to validate that the |
| 158 * given package exists. | 157 * given package exists. |
| 159 * | 158 * |
| 160 * The package name should be lower-case and suitable for use in a filename. | 159 * The package name should be lower-case and suitable for use in a filename. |
| 161 * It may contain forward slashes. | 160 * It may contain forward slashes. |
| 162 */ | 161 */ |
| 163 String packageName(description) => description; | 162 String packageName(description) => description; |
| 164 | 163 |
| 165 /** | 164 /** |
| 166 * Returns whether or not [description1] describes the same package as | 165 * Returns whether or not [description1] describes the same package as |
| 167 * [description2] for this source. This method should be light-weight. It | 166 * [description2] for this source. This method should be light-weight. It |
| 168 * doesn't need to validate that either package exists. | 167 * doesn't need to validate that either package exists. |
| 169 * | 168 * |
| 170 * By default, this assumes both descriptions are strings and compares them | 169 * By default, this assumes both descriptions are strings and compares them |
| 171 * for equality. | 170 * for equality. |
| 172 */ | 171 */ |
| 173 bool descriptionsEqual(description1, description2) => | 172 bool descriptionsEqual(description1, description2) => |
| 174 description1 == description2; | 173 description1 == description2; |
| 175 | |
| 176 /** | |
| 177 * For some sources, [PackageId]s can point to different chunks of code at | |
| 178 * different times. This takes such an [id] and returns a future that | |
| 179 * completes to a [PackageId] that will uniquely specify a single chunk of | |
| 180 * code forever. | |
| 181 * | |
| 182 * For example, [GitSource] might take an [id] with description | |
| 183 * `http://github.com/dart-lang/some-lib.git` and return an id with a | |
| 184 * description that includes the current commit of the Git repository. | |
| 185 * | |
| 186 * This will be called after the package identified by [id] is installed, so | |
| 187 * the source can use the installed package to determine information about the | |
| 188 * resolved id. | |
| 189 * | |
| 190 * The returned [PackageId] may have a description field that's invalid | |
| 191 * according to [validateDescription], although it must still be serializable | |
| 192 * to JSON and YAML. It must also be equal to [id] according to | |
| 193 * [descriptionsEqual]. | |
| 194 * | |
| 195 * By default, this just returns [id]. | |
| 196 */ | |
| 197 Future<PackageId> resolveId(PackageId id) => new Future.immediate(id); | |
| 198 } | 174 } |
| OLD | NEW |