Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: sdk/lib/_internal/pub/lib/src/package.dart

Issue 13952013: Create a "PackageRef" class that defines a versionless package reference. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 /// A reference to a [Package]. This is the common base class of [PackageId]
81 /// information to correctly install the package. 81 /// which precisely identifies a single concrete package version in the world
nweiz 2013/04/25 21:07:19 I think "in the world of packages" is more confusi
Bob Nystrom 2013/04/26 22:17:49 Done.
82 /// 82 /// of packages, and [PackageDep] which identifies one package's dependency on
nweiz 2013/04/25 21:07:19 The name "PackageDep" is fine and all, but I think
Bob Nystrom 2013/04/26 22:17:49 Done.
83 /// Note that it's possible for multiple distinct package IDs to point to 83 /// another. This class represents a reference to a conceptually identified
84 /// different directories that happen to contain identical packages. For 84 /// package.
nweiz 2013/04/25 21:07:19 "Conceptually identified" is a confusing term that
Bob Nystrom 2013/04/26 22:17:49 Done.
85 /// example, the same package may be available from multiple sources. As far as 85 class PackageRef {
86 /// Pub is concerned, those packages are different. 86 PackageRef(this.name, this.source, this.description);
87 class PackageId implements Comparable<PackageId> { 87
88 /// The name of the package being identified. 88 /// The name of the package being identified.
89 final String name; 89 final String name;
90 90
91 /// The [Source] used to look up this package given its [description]. If 91 /// The [Source] used to look up this package given its [description]. If
92 /// this is a root package ID, this will be `null`. 92 /// this is a root package ID, this will be `null`.
93 final Source source; 93 final Source source;
94 94
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 95 /// 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 96 /// 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 97 /// the package. For example, the description of a git sourced package might
101 /// by the URL "git://github.com/dart/uilib.git". 98 /// by the URL "git://github.com/dart/uilib.git".
102 final description; 99 final description;
103 100
104 PackageId(this.name, this.source, this.version, this.description); 101 int get hashCode => name.hashCode ^ source.hashCode;
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 102
113 /// Whether this ID identifies the root package. 103 /// Whether this ID identifies the root package.
114 bool get isRoot => source == null; 104 bool get isRoot => source == null;
115 105
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 106 /// Gets the directory where this package is or would be found in the
119 /// [SystemCache]. 107 /// [SystemCache].
120 Future<String> get systemCacheDirectory => source.systemCacheDirectory(this); 108 Future<String> get systemCacheDirectory => source.systemCacheDirectory(this);
121 109
122 bool operator ==(other) { 110 bool operator ==(other) {
123 if (other is! PackageId) return false; 111 // Can only be equal to other PackageRefs and not even subclasses.
124 // TODO(rnystrom): We're assuming here the name/version/source tuple is 112 if (other.runtimeType != PackageRef) return false;
125 // enough to uniquely identify the package and that we don't need to delve 113
126 // into the description. 114 // We assume here the name/source tuple is enough to identify the reference
115 // and that we don't need to delve into the description.
nweiz 2013/04/25 21:07:19 I think this should still be a TODO. "git://github
Bob Nystrom 2013/04/26 22:17:49 Done.
116 return other.name == name && other.source == source;
117 }
118
119 String toString() {
120 if (isRoot) return "$name (root)";
121 if (source.isDefault) return name;
122 return "$name from $source";
123 }
124
125 /// Returns a [PackageRef] with this one's [name], [source], and
126 /// [description]. Useful for getting a plain PackageRef from an instance of
127 /// a subclass.
128 PackageRef toRef() => new PackageRef(name, source, description);
nweiz 2013/04/25 21:07:19 This method seems weird, since every subclass shou
Bob Nystrom 2013/04/26 22:17:49 This is less weird now that PackageRef isn't the b
129
130 /// Returns a [PackageId] generated from this [PackageRef] with the given
131 /// concrete version.
132 PackageId atVersion(Version version) =>
133 new PackageId(name, source, version, description);
nweiz 2013/04/25 21:07:19 Should we have one of these to create a PackageDep
Bob Nystrom 2013/04/26 22:17:49 We don't have a use case for that yet, so in the a
134
135 /// Returns `true` if this ref's description matches [other]'s.
136 bool descriptionEquals(PackageRef other) {
137 return source.descriptionsEqual(description, other.description);
138 }
139
140 /// Gets the list of ids of all versions of the package that are described by
141 /// this reference.
nweiz 2013/04/25 21:07:19 Is this useful for anything other than PackageDep?
Bob Nystrom 2013/04/26 22:17:49 It's actually only called right now given an insta
142 Future<List<PackageId>> getVersions() {
143 if (isRoot) {
144 throw new StateError("Cannot get versions for the root package.");
145 }
146
147 return source.getVersions(name, description).then((versions) {
148 return versions.map((version) => atVersion(version)).toList();
149 });
150 }
151 }
152
153 /// An unambiguous resolved reference to a package. A package ID contains enough
nweiz 2013/04/25 21:07:19 I'd describe this as "A reference to a specific ve
Bob Nystrom 2013/04/26 22:17:49 Done.
154 /// information to correctly install the package.
155 ///
156 /// Note that it's possible for multiple distinct package IDs to point to
157 /// different directories that happen to contain identical packages. For
nweiz 2013/04/25 21:07:19 "Directories" is a little inaccurate here; I would
Bob Nystrom 2013/04/26 22:17:49 Done.
158 /// example, the same package may be available from multiple sources. As far as
159 /// Pub is concerned, those packages are different.
160 class PackageId extends PackageRef {
nweiz 2013/04/25 21:07:19 The inheritance structure of these classes is weir
Bob Nystrom 2013/04/26 22:17:49 No, it's pure code reuse.
161 /// The package's version.
162 final Version version;
163
164 PackageId(String name, Source source, this.version, description)
165 : super(name, source, description);
166
167 /// Creates an ID for the given root package.
168 PackageId.root(Package package)
169 : version = package.version,
170 super(package.name, null, package.name);
171
172 int get hashCode => name.hashCode ^ source.hashCode ^ version.hashCode;
173
174 bool operator ==(other) {
175 // Can only be equal to other PackageIds and not even subclasses.
176 if (other.runtimeType != PackageId) return false;
177
127 return other.name == name && 178 return other.name == name &&
nweiz 2013/04/25 21:07:19 Add the above TODO about description checks here a
Bob Nystrom 2013/04/26 22:17:49 Done.
128 other.source == source && 179 other.source == source &&
129 other.version == version; 180 other.version == version;
130 } 181 }
131 182
132 String toString() { 183 String toString() {
133 if (isRoot) return "$name $version (root)"; 184 if (isRoot) return "$name $version (root)";
134 if (source.isDefault) return "$name $version"; 185 if (source.isDefault) return "$name $version";
135 return "$name $version from $source"; 186 return "$name $version from $source";
136 } 187 }
137 188
138 int compareTo(PackageId other) {
nweiz 2013/04/25 21:07:19 What were we using this for?
Bob Nystrom 2013/04/26 22:17:49 I think the old solver may have used it? I'm not r
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. 189 /// Returns the pubspec for this package.
149 Future<Pubspec> describe() => source.systemCache.describe(this); 190 Future<Pubspec> describe() => source.systemCache.describe(this);
150 191
151 /// Returns a future that completes to the resovled [PackageId] for this id. 192 /// Returns a future that completes to the resolved [PackageId] for this id.
152 Future<PackageId> get resolved => source.resolveId(this); 193 Future<PackageId> get resolved => source.resolveId(this);
153 194
154 /// Returns a [PackageRef] that references this package and constrains its 195 /// Returns a [PackageDep] that references this package and constrains its
155 /// version to exactly match [version]. 196 /// version to exactly match [version].
156 PackageRef toRef() { 197 PackageDep toRef() {
157 return new PackageRef(name, source, version, description); 198 return new PackageDep(name, source, version, description);
nweiz 2013/04/25 21:07:19 Woah, this is very confusing. I expected toRef to
Bob Nystrom 2013/04/26 22:17:49 Haha, yes! Very confusing! This is an old dead me
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 } 199 }
164 } 200 }
nweiz 2013/04/25 21:07:19 If you keep getVersions in PackageRef, this should
Bob Nystrom 2013/04/26 22:17:49 It's in PackageRef, but PackageRef is no longer a
165 201
166 /// A reference to a package. Unlike a [PackageId], a PackageRef may not 202 /// A dependency on a package. Unlike a [PackageId], a PackageDep may not
nweiz 2013/04/25 21:07:19 See above about using a structure- rather than usa
Bob Nystrom 2013/04/26 22:17:49 Done.
167 /// unambiguously refer to a single package. It may describe a range of allowed 203 /// unambiguously refer to a single package. It may describe a range of allowed
168 /// packages. 204 /// packages.
169 class PackageRef { 205 class PackageDep extends 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. 206 /// The allowed package versions.
178 final VersionConstraint constraint; 207 final VersionConstraint constraint;
179 208
180 /// The metadata used to identify the package being referenced. The 209 PackageDep(String name, Source source, this.constraint, description)
181 /// interpretation of this will vary based on the [source]. 210 : 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 211
197 String toString() { 212 String toString() {
198 if (isRoot) return "$name $constraint (root)"; 213 if (isRoot) return "$name $constraint (root)";
199 return "$name $constraint from $source ($description)"; 214 return "$name $constraint from $source ($description)";
200 } 215 }
201 216
202 /// Returns a [PackageId] generated from this [PackageRef] with the given 217 bool operator ==(other) {
203 /// concrete version. 218 // Can only be equal to other PackageDeps and not even subclasses.
204 PackageId atVersion(Version version) => 219 if (other.runtimeType != PackageDep) return false;
205 new PackageId(name, source, version, description);
206 220
207 /// Returns `true` if this reference's description matches [other]'s. 221 return other.name == name &&
nweiz 2013/04/25 21:07:19 Add the TODO message here too.
Bob Nystrom 2013/04/26 22:17:49 Done.
208 bool descriptionEquals(PackageRef other) { 222 other.source == source &&
209 return source.descriptionsEqual(description, other.description); 223 other.constraint == constraint;
210 } 224 }
211 } 225 }
nweiz 2013/04/25 21:07:19 This should definitely override getVersions.
Bob Nystrom 2013/04/26 22:17:49 This no longer inherits from a type that defines t
212 226
213 class PubspecNotFoundException implements Exception { 227 class PubspecNotFoundException implements Exception {
214 final String name; 228 final String name;
215 229
216 PubspecNotFoundException(this.name); 230 PubspecNotFoundException(this.name);
217 231
218 String toString() => 'Package "$name" doesn\'t have a pubspec.yaml file.'; 232 String toString() => 'Package "$name" doesn\'t have a pubspec.yaml file.';
219 } 233 }
220 234
221 class PubspecHasNoNameException implements Exception { 235 class PubspecHasNoNameException implements Exception {
222 final String name; 236 final String name;
223 237
224 PubspecHasNoNameException(this.name); 238 PubspecHasNoNameException(this.name);
225 239
226 String toString() => 'Package "$name"\'s pubspec.yaml file is missing the ' 240 String toString() => 'Package "$name"\'s pubspec.yaml file is missing the '
227 'required "name" field (e.g. "name: $name").'; 241 'required "name" field (e.g. "name: $name").';
228 } 242 }
229 243
230 class PubspecNameMismatchException implements Exception { 244 class PubspecNameMismatchException implements Exception {
231 final String expectedName; 245 final String expectedName;
232 final String actualName; 246 final String actualName;
233 247
234 PubspecNameMismatchException(this.expectedName, this.actualName); 248 PubspecNameMismatchException(this.expectedName, this.actualName);
235 249
236 String toString() => 'The name you specified for your dependency, ' 250 String toString() => 'The name you specified for your dependency, '
237 '"$expectedName", doesn\'t match the name "$actualName" in its pubspec.'; 251 '"$expectedName", doesn\'t match the name "$actualName" in its pubspec.';
238 } 252 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698