| 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 package; | 5 library package; |
| 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 18 matching lines...) Expand all Loading... |
| 29 } | 29 } |
| 30 | 30 |
| 31 /// The package's version. | 31 /// The package's version. |
| 32 Version get version => pubspec.version; | 32 Version get version => pubspec.version; |
| 33 | 33 |
| 34 /// The parsed pubspec associated with this package. | 34 /// The parsed pubspec associated with this package. |
| 35 final Pubspec pubspec; | 35 final Pubspec pubspec; |
| 36 | 36 |
| 37 /// The ids of the packages that this package depends on. This is what is | 37 /// The ids of the packages that this package depends on. This is what is |
| 38 /// specified in the pubspec when this package depends on another. | 38 /// specified in the pubspec when this package depends on another. |
| 39 List<PackageRef> get dependencies => pubspec.dependencies; | 39 List<PackageDep> get dependencies => pubspec.dependencies; |
| 40 | 40 |
| 41 /// Returns the path to the README file at the root of the entrypoint, or null | 41 /// Returns the path to the README file at the root of the entrypoint, or null |
| 42 /// if no README file is found. If multiple READMEs are found, this uses the | 42 /// if no README file is found. If multiple READMEs are found, this uses the |
| 43 /// same conventions as pub.dartlang.org for choosing the primary one: the | 43 /// same conventions as pub.dartlang.org for choosing the primary one: the |
| 44 /// README with the fewest extensions that is lexically ordered first is | 44 /// README with the fewest extensions that is lexically ordered first is |
| 45 /// chosen. | 45 /// chosen. |
| 46 String get readmePath { | 46 String get readmePath { |
| 47 var readmes = listDir(dir).map(path.basename). | 47 var readmes = listDir(dir).map(path.basename). |
| 48 where((entry) => entry.contains(_README_REGEXP)); | 48 where((entry) => entry.contains(_README_REGEXP)); |
| 49 if (readmes.isEmpty) return null; | 49 if (readmes.isEmpty) return null; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 70 : dir = null; | 70 : dir = null; |
| 71 | 71 |
| 72 /// Constructs a package. This should not be called directly. Instead, acquire | 72 /// Constructs a package. This should not be called directly. Instead, acquire |
| 73 /// packages from [load()]. | 73 /// packages from [load()]. |
| 74 Package._(this.dir, this.pubspec); | 74 Package._(this.dir, this.pubspec); |
| 75 | 75 |
| 76 /// Returns a debug string for the package. | 76 /// Returns a debug string for the package. |
| 77 String toString() => '$name $version ($dir)'; | 77 String toString() => '$name $version ($dir)'; |
| 78 } | 78 } |
| 79 | 79 |
| 80 /// An unambiguous resolved reference to a package. A package ID contains enough | 80 /// This is the private base class of [PackageRef], [PackageID], and |
| 81 /// information to correctly install the package. | 81 /// [PackageDep]. It contains functionality and state that those classes share |
| 82 /// | 82 /// but is private so that from outside of this library, there is no type |
| 83 /// Note that it's possible for multiple distinct package IDs to point to | 83 /// relationship between those three types. |
| 84 /// different directories that happen to contain identical packages. For | 84 class _PackageName { |
| 85 /// example, the same package may be available from multiple sources. As far as | 85 _PackageName(this.name, this.source, this.description); |
| 86 /// Pub is concerned, those packages are different. | 86 |
| 87 class PackageId implements Comparable<PackageId> { | |
| 88 /// The name of the package being identified. | 87 /// The name of the package being identified. |
| 89 final String name; | 88 final String name; |
| 90 | 89 |
| 91 /// The [Source] used to look up this package given its [description]. If | 90 /// The [Source] used to look up this package given its [description]. If |
| 92 /// this is a root package ID, this will be `null`. | 91 /// this is a root package, this will be `null`. |
| 93 final Source source; | 92 final Source source; |
| 94 | 93 |
| 95 /// The package's version. | |
| 96 final Version version; | |
| 97 | |
| 98 /// The metadata used by the package's [source] to identify and locate it. It | 94 /// The metadata used by the package's [source] to identify and locate it. It |
| 99 /// contains whatever [Source]-specific data it needs to be able to install | 95 /// contains whatever [Source]-specific data it needs to be able to install |
| 100 /// the package. For example, the description of a git sourced package might | 96 /// the package. For example, the description of a git sourced package might |
| 101 /// by the URL "git://github.com/dart/uilib.git". | 97 /// by the URL "git://github.com/dart/uilib.git". |
| 102 final description; | 98 final description; |
| 103 | 99 |
| 104 PackageId(this.name, this.source, this.version, this.description); | 100 /// Whether this package is the root package. |
| 105 | |
| 106 /// Creates an ID for the given root package. | |
| 107 PackageId.root(Package package) | |
| 108 : name = package.name, | |
| 109 source = null, | |
| 110 version = package.version, | |
| 111 description = package.name; | |
| 112 | |
| 113 /// Whether this ID identifies the root package. | |
| 114 bool get isRoot => source == null; | 101 bool get isRoot => source == null; |
| 115 | 102 |
| 116 int get hashCode => name.hashCode ^ source.hashCode ^ version.hashCode; | |
| 117 | |
| 118 /// Gets the directory where this package is or would be found in the | 103 /// Gets the directory where this package is or would be found in the |
| 119 /// [SystemCache]. | 104 /// [SystemCache]. |
| 120 Future<String> get systemCacheDirectory => source.systemCacheDirectory(this); | 105 Future<String> get systemCacheDirectory => source.systemCacheDirectory(this); |
| 121 | 106 |
| 107 String toString() { |
| 108 if (isRoot) return "$name (root)"; |
| 109 if (source.isDefault) return name; |
| 110 return "$name from $source"; |
| 111 } |
| 112 |
| 113 /// Returns a [PackageRef] with this one's [name], [source], and |
| 114 /// [description]. |
| 115 PackageRef toRef() => new PackageRef(name, source, description); |
| 116 |
| 117 /// Returns a [PackageId] for this package with the given concrete version. |
| 118 PackageId atVersion(Version version) => |
| 119 new PackageId(name, source, version, description); |
| 120 |
| 121 /// Returns `true` if this package's description matches [other]'s. |
| 122 bool descriptionEquals(PackageDep other) { |
| 123 return source.descriptionsEqual(description, other.description); |
| 124 } |
| 125 } |
| 126 |
| 127 /// A reference to a [Package], but not any particular version(s) of it. |
| 128 class PackageRef extends _PackageName { |
| 129 PackageRef(String name, Source source, description) |
| 130 : super(name, source, description); |
| 131 |
| 132 int get hashCode => name.hashCode ^ source.hashCode; |
| 133 |
| 122 bool operator ==(other) { | 134 bool operator ==(other) { |
| 123 if (other is! PackageId) return false; | 135 // TODO(rnystrom): We're assuming here that we don't need to delve into the |
| 124 // TODO(rnystrom): We're assuming here the name/version/source tuple is | 136 // description. |
| 125 // enough to uniquely identify the package and that we don't need to delve | 137 return other is PackageRef && |
| 126 // into the description. | 138 other.name == name && |
| 127 return other.name == name && | 139 other.source == source; |
| 140 } |
| 141 |
| 142 /// Gets the list of ids of all versions of the package that are described by |
| 143 /// this reference. |
| 144 Future<List<PackageId>> getVersions() { |
| 145 if (isRoot) { |
| 146 throw new StateError("Cannot get versions for the root package."); |
| 147 } |
| 148 |
| 149 return source.getVersions(name, description).then((versions) { |
| 150 return versions.map((version) => atVersion(version)).toList(); |
| 151 }); |
| 152 } |
| 153 } |
| 154 |
| 155 /// A reference to a specific version of a package. A package ID contains |
| 156 /// enough information to correctly install the package. |
| 157 /// |
| 158 /// Note that it's possible for multiple distinct package IDs to point to |
| 159 /// different packages that have identical contents. For example, the same |
| 160 /// package may be available from multiple sources. As far as Pub is concerned, |
| 161 /// those packages are different. |
| 162 class PackageId extends _PackageName { |
| 163 /// The package's version. |
| 164 final Version version; |
| 165 |
| 166 PackageId(String name, Source source, this.version, description) |
| 167 : super(name, source, description); |
| 168 |
| 169 /// Creates an ID for the given root package. |
| 170 PackageId.root(Package package) |
| 171 : version = package.version, |
| 172 super(package.name, null, package.name); |
| 173 |
| 174 int get hashCode => name.hashCode ^ source.hashCode ^ version.hashCode; |
| 175 |
| 176 bool operator ==(other) { |
| 177 // TODO(rnystrom): We're assuming here that we don't need to delve into the |
| 178 // description. |
| 179 return other is PackageId && |
| 180 other.name == name && |
| 128 other.source == source && | 181 other.source == source && |
| 129 other.version == version; | 182 other.version == version; |
| 130 } | 183 } |
| 131 | 184 |
| 132 String toString() { | 185 String toString() { |
| 133 if (isRoot) return "$name $version (root)"; | 186 if (isRoot) return "$name $version (root)"; |
| 134 if (source.isDefault) return "$name $version"; | 187 if (source.isDefault) return "$name $version"; |
| 135 return "$name $version from $source"; | 188 return "$name $version from $source"; |
| 136 } | 189 } |
| 137 | 190 |
| 138 int compareTo(PackageId other) { | |
| 139 var sourceComp = source.name.compareTo(other.source.name); | |
| 140 if (sourceComp != 0) return sourceComp; | |
| 141 | |
| 142 var nameComp = name.compareTo(other.name); | |
| 143 if (nameComp != 0) return nameComp; | |
| 144 | |
| 145 return version.compareTo(other.version); | |
| 146 } | |
| 147 | |
| 148 /// Returns the pubspec for this package. | 191 /// Returns the pubspec for this package. |
| 149 Future<Pubspec> describe() => source.systemCache.describe(this); | 192 Future<Pubspec> describe() => source.systemCache.describe(this); |
| 150 | 193 |
| 151 /// Returns a future that completes to the resovled [PackageId] for this id. | 194 /// Returns a future that completes to the resolved [PackageId] for this id. |
| 152 Future<PackageId> get resolved => source.resolveId(this); | 195 Future<PackageId> get resolved => source.resolveId(this); |
| 153 | |
| 154 /// Returns a [PackageRef] that references this package and constrains its | |
| 155 /// version to exactly match [version]. | |
| 156 PackageRef toRef() { | |
| 157 return new PackageRef(name, source, version, description); | |
| 158 } | |
| 159 | |
| 160 /// Returns `true` if this id's description matches [other]'s. | |
| 161 bool descriptionEquals(PackageRef other) { | |
| 162 return source.descriptionsEqual(description, other.description); | |
| 163 } | |
| 164 } | 196 } |
| 165 | 197 |
| 166 /// A reference to a package. Unlike a [PackageId], a PackageRef may not | 198 /// A reference to a constrained range of versions of one package. |
| 167 /// unambiguously refer to a single package. It may describe a range of allowed | 199 class PackageDep extends _PackageName { |
| 168 /// packages. | |
| 169 class PackageRef { | |
| 170 /// The name of the package being identified. | |
| 171 final String name; | |
| 172 | |
| 173 /// The [Source] used to look up the package. If this refers to a root | |
| 174 /// package, this will be `null`. | |
| 175 final Source source; | |
| 176 | |
| 177 /// The allowed package versions. | 200 /// The allowed package versions. |
| 178 final VersionConstraint constraint; | 201 final VersionConstraint constraint; |
| 179 | 202 |
| 180 /// The metadata used to identify the package being referenced. The | 203 PackageDep(String name, Source source, this.constraint, description) |
| 181 /// interpretation of this will vary based on the [source]. | 204 : super(name, source, description); |
| 182 final description; | |
| 183 | |
| 184 PackageRef(this.name, this.source, this.constraint, this.description); | |
| 185 | |
| 186 // TODO(rnystrom): Remove this if the old version solver is removed. | |
| 187 /// Creates a reference to the given root package. | |
| 188 PackageRef.root(Package package) | |
| 189 : name = package.name, | |
| 190 source = null, | |
| 191 constraint = package.version, | |
| 192 description = package.name; | |
| 193 | |
| 194 /// Whether this refers to the root package. | |
| 195 bool get isRoot => source == null; | |
| 196 | 205 |
| 197 String toString() { | 206 String toString() { |
| 198 if (isRoot) return "$name $constraint (root)"; | 207 if (isRoot) return "$name $constraint (root)"; |
| 199 return "$name $constraint from $source ($description)"; | 208 return "$name $constraint from $source ($description)"; |
| 200 } | 209 } |
| 201 | 210 |
| 202 /// Returns a [PackageId] generated from this [PackageRef] with the given | 211 int get hashCode => name.hashCode ^ source.hashCode; |
| 203 /// concrete version. | |
| 204 PackageId atVersion(Version version) => | |
| 205 new PackageId(name, source, version, description); | |
| 206 | 212 |
| 207 /// Returns `true` if this reference's description matches [other]'s. | 213 bool operator ==(other) { |
| 208 bool descriptionEquals(PackageRef other) { | 214 // TODO(rnystrom): We're assuming here that we don't need to delve into the |
| 209 return source.descriptionsEqual(description, other.description); | 215 // description. |
| 216 return other is PackageDep && |
| 217 other.name == name && |
| 218 other.source == source && |
| 219 other.constraint == constraint; |
| 210 } | 220 } |
| 211 } | 221 } |
| 212 | 222 |
| 213 class PubspecNotFoundException implements Exception { | 223 class PubspecNotFoundException implements Exception { |
| 214 final String name; | 224 final String name; |
| 215 | 225 |
| 216 PubspecNotFoundException(this.name); | 226 PubspecNotFoundException(this.name); |
| 217 | 227 |
| 218 String toString() => 'Package "$name" doesn\'t have a pubspec.yaml file.'; | 228 String toString() => 'Package "$name" doesn\'t have a pubspec.yaml file.'; |
| 219 } | 229 } |
| 220 | 230 |
| 221 class PubspecHasNoNameException implements Exception { | 231 class PubspecHasNoNameException implements Exception { |
| 222 final String name; | 232 final String name; |
| 223 | 233 |
| 224 PubspecHasNoNameException(this.name); | 234 PubspecHasNoNameException(this.name); |
| 225 | 235 |
| 226 String toString() => 'Package "$name"\'s pubspec.yaml file is missing the ' | 236 String toString() => 'Package "$name"\'s pubspec.yaml file is missing the ' |
| 227 'required "name" field (e.g. "name: $name").'; | 237 'required "name" field (e.g. "name: $name").'; |
| 228 } | 238 } |
| 229 | 239 |
| 230 class PubspecNameMismatchException implements Exception { | 240 class PubspecNameMismatchException implements Exception { |
| 231 final String expectedName; | 241 final String expectedName; |
| 232 final String actualName; | 242 final String actualName; |
| 233 | 243 |
| 234 PubspecNameMismatchException(this.expectedName, this.actualName); | 244 PubspecNameMismatchException(this.expectedName, this.actualName); |
| 235 | 245 |
| 236 String toString() => 'The name you specified for your dependency, ' | 246 String toString() => 'The name you specified for your dependency, ' |
| 237 '"$expectedName", doesn\'t match the name "$actualName" in its pubspec.'; | 247 '"$expectedName", doesn\'t match the name "$actualName" in its pubspec.'; |
| 238 } | 248 } |
| OLD | NEW |