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

Side by Side Diff: mojo/public/dart/third_party/pub_semver/lib/src/version_range.dart

Issue 1346773002: Stop running pub get at gclient sync time and fix build bugs (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 3 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
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
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.
4
5 library pub_semver.src.version_range;
6
7 import 'version.dart';
8 import 'version_constraint.dart';
9 import 'version_union.dart';
10
11 /// Constrains versions to a fall within a given range.
12 ///
13 /// If there is a minimum, then this only allows versions that are at that
14 /// minimum or greater. If there is a maximum, then only versions less than
15 /// that are allowed. In other words, this allows `>= min, < max`.
16 class VersionRange implements VersionConstraint {
17 /// The minimum end of the range.
18 ///
19 /// If [includeMin] is `true`, this will be the minimum allowed version.
20 /// Otherwise, it will be the highest version below the range that is not
21 /// allowed.
22 ///
23 /// This may be `null` in which case the range has no minimum end and allows
24 /// any version less than the maximum.
25 final Version min;
26
27 /// The maximum end of the range.
28 ///
29 /// If [includeMax] is `true`, this will be the maximum allowed version.
30 /// Otherwise, it will be the lowest version above the range that is not
31 /// allowed.
32 ///
33 /// This may be `null` in which case the range has no maximum end and allows
34 /// any version greater than the minimum.
35 final Version max;
36
37 /// If `true` then [min] is allowed by the range.
38 final bool includeMin;
39
40 /// If `true`, then [max] is allowed by the range.
41 final bool includeMax;
42
43 /// Creates a new version range from [min] to [max], either inclusive or
44 /// exclusive.
45 ///
46 /// If it is an error if [min] is greater than [max].
47 ///
48 /// Either [max] or [min] may be omitted to not clamp the range at that end.
49 /// If both are omitted, the range allows all versions.
50 ///
51 /// If [includeMin] is `true`, then the minimum end of the range is inclusive.
52 /// Likewise, passing [includeMax] as `true` makes the upper end inclusive.
53 VersionRange({this.min, this.max,
54 this.includeMin: false, this.includeMax: false}) {
55 if (min != null && max != null && min > max) {
56 throw new ArgumentError(
57 'Minimum version ("$min") must be less than maximum ("$max").');
58 }
59 }
60
61 bool operator ==(other) {
62 if (other is! VersionRange) return false;
63
64 return min == other.min &&
65 max == other.max &&
66 includeMin == other.includeMin &&
67 includeMax == other.includeMax;
68 }
69
70 int get hashCode => min.hashCode ^ (max.hashCode * 3) ^
71 (includeMin.hashCode * 5) ^ (includeMax.hashCode * 7);
72
73 bool get isEmpty => false;
74
75 bool get isAny => min == null && max == null;
76
77 /// Tests if [other] falls within this version range.
78 bool allows(Version other) {
79 if (min != null) {
80 if (other < min) return false;
81 if (!includeMin && other == min) return false;
82 }
83
84 if (max != null) {
85 if (other > max) return false;
86 if (!includeMax && other == max) return false;
87
88
89 // Disallow pre-release versions that have the same major, minor, and
90 // patch version as the max, but only if neither the max nor the min is a
91 // pre-release of that version. This ensures that "^1.2.3" doesn't include
92 // "2.0.0-pre", while also allowing both ">=2.0.0-pre.2 <2.0.0" and
93 // ">=1.2.3 <2.0.0-pre.7" to match "2.0.0-pre.5".
94 //
95 // It's worth noting that this is different than [NPM's semantics][]. NPM
96 // disallows **all** pre-release versions unless their major, minor, and
97 // patch numbers match those of a prerelease min or max. This ensures that
98 // no prerelease versions will ever be selected if the user doesn't
99 // explicitly allow them.
100 //
101 // [NPM's semantics]: https://www.npmjs.org/doc/misc/semver.html#prereleas e-tags
102 //
103 // Instead, we ensure that release versions will always be preferred over
104 // prerelease versions by ordering the release versions first in
105 // [Version.prioritize]. This means that constraints like "any" or
106 // ">1.2.3" can still match prerelease versions if they're the only things
107 // available.
108 var maxIsReleaseOfOther = !includeMax &&
109 !max.isPreRelease && other.isPreRelease &&
110 _equalsWithoutPreRelease(other, max);
111 var minIsPreReleaseOfOther = min != null && min.isPreRelease &&
112 _equalsWithoutPreRelease(other, min);
113 if (maxIsReleaseOfOther && !minIsPreReleaseOfOther) return false;
114 }
115
116 return true;
117 }
118
119 bool _equalsWithoutPreRelease(Version version1, Version version2) =>
120 version1.major == version2.major &&
121 version1.minor == version2.minor &&
122 version1.patch == version2.patch;
123
124 bool allowsAll(VersionConstraint other) {
125 if (other.isEmpty) return true;
126 if (other is Version) return allows(other);
127
128 if (other is VersionUnion) {
129 return other.constraints.every((constraint) => allowsAll(constraint));
130 }
131
132 if (other is VersionRange) {
133 if (min != null) {
134 if (other.min == null) return false;
135 if (min > other.min) return false;
136 if (min == other.min && !includeMin && other.includeMin) return false;
137 }
138
139 if (max != null) {
140 if (other.max == null) return false;
141 if (max < other.max) return false;
142 if (max == other.max && !includeMax && other.includeMax) return false;
143 }
144
145 return true;
146 }
147
148 throw new ArgumentError('Unknown VersionConstraint type $other.');
149 }
150
151 bool allowsAny(VersionConstraint other) {
152 if (other.isEmpty) return false;
153 if (other is Version) return allows(other);
154
155 if (other is VersionUnion) {
156 return other.constraints.any((constraint) => allowsAny(constraint));
157 }
158
159 if (other is VersionRange) {
160 // If neither range has a minimum, they'll overlap at some point.
161 //
162 // ... this ]
163 // ... other ]
164 if (min == null && other.min == null) return true;
165
166 // If this range has a lower minimum than the other range, it overlaps as
167 // long as its maximum is higher than or the same as the other range's
168 // minimum.
169 //
170 // [ this ] [ this ]
171 // [ other ] [ other ]
172 if (min == null || (other.min != null && min < other.min)) {
173 if (max == null) return true;
174 if (max > other.min) return true;
175 if (max < other.min) return false;
176 assert(max == other.min);
177 return includeMax && other.includeMin;
178 }
179
180 // If this range has a higher minimum than the other range, it overlaps as
181 // long as its minimum is lower than or the same as the other range's
182 // maximum.
183 //
184 // [ this ] [ this ]
185 // [ other ] [ other ]
186 if (other.max == null) return true;
187 if (min < other.max) return true;
188 if (min > other.max) return false;
189 assert(min == other.max);
190 return includeMin && other.includeMax;
191 }
192
193 throw new ArgumentError('Unknown VersionConstraint type $other.');
194 }
195
196 VersionConstraint intersect(VersionConstraint other) {
197 if (other.isEmpty) return other;
198 if (other is VersionUnion) return other.intersect(this);
199
200 // A range and a Version just yields the version if it's in the range.
201 if (other is Version) {
202 return allows(other) ? other : VersionConstraint.empty;
203 }
204
205 if (other is VersionRange) {
206 // Intersect the two ranges.
207 var intersectMin = min;
208 var intersectIncludeMin = includeMin;
209 var intersectMax = max;
210 var intersectIncludeMax = includeMax;
211
212 if (other.min == null) {
213 // Do nothing.
214 } else if (intersectMin == null || intersectMin < other.min) {
215 intersectMin = other.min;
216 intersectIncludeMin = other.includeMin;
217 } else if (intersectMin == other.min && !other.includeMin) {
218 // The edges are the same, but one is exclusive, make it exclusive.
219 intersectIncludeMin = false;
220 }
221
222 if (other.max == null) {
223 // Do nothing.
224 } else if (intersectMax == null || intersectMax > other.max) {
225 intersectMax = other.max;
226 intersectIncludeMax = other.includeMax;
227 } else if (intersectMax == other.max && !other.includeMax) {
228 // The edges are the same, but one is exclusive, make it exclusive.
229 intersectIncludeMax = false;
230 }
231
232 if (intersectMin == null && intersectMax == null) {
233 // Open range.
234 return new VersionRange();
235 }
236
237 // If the range is just a single version.
238 if (intersectMin == intersectMax) {
239 // If both ends are inclusive, allow that version.
240 if (intersectIncludeMin && intersectIncludeMax) return intersectMin;
241
242 // Otherwise, no versions.
243 return VersionConstraint.empty;
244 }
245
246 if (intersectMin != null && intersectMax != null &&
247 intersectMin > intersectMax) {
248 // Non-overlapping ranges, so empty.
249 return VersionConstraint.empty;
250 }
251
252 // If we got here, there is an actual range.
253 return new VersionRange(min: intersectMin, max: intersectMax,
254 includeMin: intersectIncludeMin, includeMax: intersectIncludeMax);
255 }
256
257 throw new ArgumentError('Unknown VersionConstraint type $other.');
258 }
259
260 VersionConstraint union(VersionConstraint other) {
261 if (other is Version) {
262 if (allows(other)) return this;
263
264 if (other == min) {
265 return new VersionRange(
266 min: this.min, max: this.max,
267 includeMin: true, includeMax: this.includeMax);
268 }
269
270 if (other == max) {
271 return new VersionRange(
272 min: this.min, max: this.max,
273 includeMin: this.includeMin, includeMax: true);
274 }
275
276 return new VersionConstraint.unionOf([this, other]);
277 }
278
279 if (other is VersionRange) {
280 // If the two ranges don't overlap, we won't be able to create a single
281 // VersionRange for both of them.
282 var edgesTouch = (max == other.min && (includeMax || other.includeMin)) ||
283 (min == other.max && (includeMin || other.includeMax));
284 if (!edgesTouch && !allowsAny(other)) {
285 return new VersionConstraint.unionOf([this, other]);
286 }
287
288 var unionMin = min;
289 var unionIncludeMin = includeMin;
290 var unionMax = max;
291 var unionIncludeMax = includeMax;
292
293 if (unionMin == null) {
294 // Do nothing.
295 } else if (other.min == null || other.min < min) {
296 unionMin = other.min;
297 unionIncludeMin = other.includeMin;
298 } else if (min == other.min && other.includeMin) {
299 // If the edges are the same but one is inclusive, make it inclusive.
300 unionIncludeMin = true;
301 }
302
303 if (unionMax == null) {
304 // Do nothing.
305 } else if (other.max == null || other.max > max) {
306 unionMax = other.max;
307 unionIncludeMax = other.includeMax;
308 } else if (max == other.max && other.includeMax) {
309 // If the edges are the same but one is inclusive, make it inclusive.
310 unionIncludeMax = true;
311 }
312
313 return new VersionRange(min: unionMin, max: unionMax,
314 includeMin: unionIncludeMin, includeMax: unionIncludeMax);
315 }
316
317 return new VersionConstraint.unionOf([this, other]);
318 }
319
320 String toString() {
321 var buffer = new StringBuffer();
322
323 if (min != null) {
324 buffer.write(includeMin ? '>=' : '>');
325 buffer.write(min);
326 }
327
328 if (max != null) {
329 if (min != null) buffer.write(' ');
330 buffer.write(includeMax ? '<=' : '<');
331 buffer.write(max);
332 }
333
334 if (min == null && max == null) buffer.write('any');
335 return buffer.toString();
336 }
337 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698