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

Side by Side Diff: mojo/public/dart/third_party/pub_semver/lib/src/version.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;
6
7 import 'dart:math' as math;
8
9 import 'package:collection/equality.dart';
10
11 import 'patterns.dart';
12 import 'version_constraint.dart';
13 import 'version_range.dart';
14
15 /// The equality operator to use for comparing version components.
16 final _equality = const IterableEquality();
17
18 /// A parsed semantic version number.
19 class Version implements Comparable<Version>, VersionConstraint, VersionRange {
20 /// No released version: i.e. "0.0.0".
21 static Version get none => new Version(0, 0, 0);
22
23 /// Compares [a] and [b] to see which takes priority over the other.
24 ///
25 /// Returns `1` if [a] takes priority over [b] and `-1` if vice versa. If
26 /// [a] and [b] are equivalent, returns `0`.
27 ///
28 /// Unlike [compareTo], which *orders* versions, this determines which
29 /// version a user is likely to prefer. In particular, it prioritizes
30 /// pre-release versions lower than stable versions, regardless of their
31 /// version numbers. Pub uses this when determining which version to prefer
32 /// when a number of versions are allowed. In that case, it will always
33 /// choose a stable version when possible.
34 ///
35 /// When used to sort a list, orders in ascending priority so that the
36 /// highest priority version is *last* in the result.
37 static int prioritize(Version a, Version b) {
38 // Sort all prerelease versions after all normal versions. This way
39 // the solver will prefer stable packages over unstable ones.
40 if (a.isPreRelease && !b.isPreRelease) return -1;
41 if (!a.isPreRelease && b.isPreRelease) return 1;
42
43 return a.compareTo(b);
44 }
45
46 /// Like [prioritize], but lower version numbers are considered greater than
47 /// higher version numbers.
48 ///
49 /// This still considers prerelease versions to be lower than non-prerelease
50 /// versions. Pub uses this when downgrading -- it chooses the lowest version
51 /// but still excludes pre-release versions when possible.
52 static int antiprioritize(Version a, Version b) {
53 if (a.isPreRelease && !b.isPreRelease) return -1;
54 if (!a.isPreRelease && b.isPreRelease) return 1;
55
56 return b.compareTo(a);
57 }
58
59 /// The major version number: "1" in "1.2.3".
60 final int major;
61
62 /// The minor version number: "2" in "1.2.3".
63 final int minor;
64
65 /// The patch version number: "3" in "1.2.3".
66 final int patch;
67
68 /// The pre-release identifier: "foo" in "1.2.3-foo".
69 ///
70 /// This is split into a list of components, each of which may be either a
71 /// string or a non-negative integer. It may also be empty, indicating that
72 /// this version has no pre-release identifier.
73 final List preRelease;
74
75 /// The build identifier: "foo" in "1.2.3+foo".
76 ///
77 /// This is split into a list of components, each of which may be either a
78 /// string or a non-negative integer. It may also be empty, indicating that
79 /// this version has no build identifier.
80 final List build;
81
82 /// The original string representation of the version number.
83 ///
84 /// This preserves textual artifacts like leading zeros that may be left out
85 /// of the parsed version.
86 final String _text;
87
88 Version get min => this;
89 Version get max => this;
90 bool get includeMin => true;
91 bool get includeMax => true;
92
93 Version._(this.major, this.minor, this.patch, String preRelease, String build,
94 this._text)
95 : preRelease = preRelease == null ? [] : _splitParts(preRelease),
96 build = build == null ? [] : _splitParts(build) {
97 if (major < 0) throw new ArgumentError(
98 'Major version must be non-negative.');
99 if (minor < 0) throw new ArgumentError(
100 'Minor version must be non-negative.');
101 if (patch < 0) throw new ArgumentError(
102 'Patch version must be non-negative.');
103 }
104
105 /// Creates a new [Version] object.
106 factory Version(int major, int minor, int patch, {String pre, String build}) {
107 var text = "$major.$minor.$patch";
108 if (pre != null) text += "-$pre";
109 if (build != null) text += "+$build";
110
111 return new Version._(major, minor, patch, pre, build, text);
112 }
113
114 /// Creates a new [Version] by parsing [text].
115 factory Version.parse(String text) {
116 final match = COMPLETE_VERSION.firstMatch(text);
117 if (match == null) {
118 throw new FormatException('Could not parse "$text".');
119 }
120
121 try {
122 int major = int.parse(match[1]);
123 int minor = int.parse(match[2]);
124 int patch = int.parse(match[3]);
125
126 String preRelease = match[5];
127 String build = match[8];
128
129 return new Version._(major, minor, patch, preRelease, build, text);
130 } on FormatException {
131 throw new FormatException('Could not parse "$text".');
132 }
133 }
134
135 /// Returns the primary version out of a list of candidates.
136 ///
137 /// This is the highest-numbered stable (non-prerelease) version. If there
138 /// are no stable versions, it's just the highest-numbered version.
139 static Version primary(List<Version> versions) {
140 var primary;
141 for (var version in versions) {
142 if (primary == null || (!version.isPreRelease && primary.isPreRelease) ||
143 (version.isPreRelease == primary.isPreRelease && version > primary)) {
144 primary = version;
145 }
146 }
147 return primary;
148 }
149
150 /// Splits a string of dot-delimited identifiers into their component parts.
151 ///
152 /// Identifiers that are numeric are converted to numbers.
153 static List _splitParts(String text) {
154 return text.split('.').map((part) {
155 try {
156 return int.parse(part);
157 } on FormatException {
158 // Not a number.
159 return part;
160 }
161 }).toList();
162 }
163
164 bool operator ==(other) {
165 if (other is! Version) return false;
166 return major == other.major && minor == other.minor &&
167 patch == other.patch &&
168 _equality.equals(preRelease, other.preRelease) &&
169 _equality.equals(build, other.build);
170 }
171
172 int get hashCode => major ^ minor ^ patch ^ _equality.hash(preRelease) ^
173 _equality.hash(build);
174
175 bool operator <(Version other) => compareTo(other) < 0;
176 bool operator >(Version other) => compareTo(other) > 0;
177 bool operator <=(Version other) => compareTo(other) <= 0;
178 bool operator >=(Version other) => compareTo(other) >= 0;
179
180 bool get isAny => false;
181 bool get isEmpty => false;
182
183 /// Whether or not this is a pre-release version.
184 bool get isPreRelease => preRelease.isNotEmpty;
185
186 /// Gets the next major version number that follows this one.
187 ///
188 /// If this version is a pre-release of a major version release (i.e. the
189 /// minor and patch versions are zero), then it just strips the pre-release
190 /// suffix. Otherwise, it increments the major version and resets the minor
191 /// and patch.
192 Version get nextMajor {
193 if (isPreRelease && minor == 0 && patch == 0) {
194 return new Version(major, minor, patch);
195 }
196
197 return _incrementMajor();
198 }
199
200 /// Gets the next minor version number that follows this one.
201 ///
202 /// If this version is a pre-release of a minor version release (i.e. the
203 /// patch version is zero), then it just strips the pre-release suffix.
204 /// Otherwise, it increments the minor version and resets the patch.
205 Version get nextMinor {
206 if (isPreRelease && patch == 0) {
207 return new Version(major, minor, patch);
208 }
209
210 return _incrementMinor();
211 }
212
213 /// Gets the next patch version number that follows this one.
214 ///
215 /// If this version is a pre-release, then it just strips the pre-release
216 /// suffix. Otherwise, it increments the patch version.
217 Version get nextPatch {
218 if (isPreRelease) {
219 return new Version(major, minor, patch);
220 }
221
222 return _incrementPatch();
223 }
224
225 /// Gets the next breaking version number that follows this one.
226 ///
227 /// Increments [major] if it's greater than zero, otherwise [minor], resets
228 /// subsequent digits to zero, and strips any [preRelease] or [build]
229 /// suffix.
230 Version get nextBreaking {
231 if (major == 0) {
232 return _incrementMinor();
233 }
234
235 return _incrementMajor();
236 }
237
238 Version _incrementMajor() => new Version(major + 1, 0, 0);
239 Version _incrementMinor() => new Version(major, minor + 1, 0);
240 Version _incrementPatch() => new Version(major, minor, patch + 1);
241
242 /// Tests if [other] matches this version exactly.
243 bool allows(Version other) => this == other;
244
245 bool allowsAll(VersionConstraint other) => other.isEmpty || other == this;
246
247 bool allowsAny(VersionConstraint other) => other.allows(this);
248
249 VersionConstraint intersect(VersionConstraint other) =>
250 other.allows(this) ? this : VersionConstraint.empty;
251
252 VersionConstraint union(VersionConstraint other) {
253 if (other.allows(this)) return other;
254
255 if (other is VersionRange) {
256 if (other.min == this) {
257 return new VersionRange(
258 min: other.min, max: other.max,
259 includeMin: true, includeMax: other.includeMax);
260 }
261
262 if (other.max == this) {
263 return new VersionRange(
264 min: other.min, max: other.max,
265 includeMin: other.includeMin, includeMax: true);
266 }
267 }
268
269 return new VersionConstraint.unionOf([this, other]);
270 }
271
272 int compareTo(Version other) {
273 if (major != other.major) return major.compareTo(other.major);
274 if (minor != other.minor) return minor.compareTo(other.minor);
275 if (patch != other.patch) return patch.compareTo(other.patch);
276
277 // Pre-releases always come before no pre-release string.
278 if (!isPreRelease && other.isPreRelease) return 1;
279 if (!other.isPreRelease && isPreRelease) return -1;
280
281 var comparison = _compareLists(preRelease, other.preRelease);
282 if (comparison != 0) return comparison;
283
284 // Builds always come after no build string.
285 if (build.isEmpty && other.build.isNotEmpty) return -1;
286 if (other.build.isEmpty && build.isNotEmpty) return 1;
287 return _compareLists(build, other.build);
288 }
289
290 String toString() => _text;
291
292 /// Compares a dot-separated component of two versions.
293 ///
294 /// This is used for the pre-release and build version parts. This follows
295 /// Rule 12 of the Semantic Versioning spec (v2.0.0-rc.1).
296 int _compareLists(List a, List b) {
297 for (var i = 0; i < math.max(a.length, b.length); i++) {
298 var aPart = (i < a.length) ? a[i] : null;
299 var bPart = (i < b.length) ? b[i] : null;
300
301 if (aPart == bPart) continue;
302
303 // Missing parts come before present ones.
304 if (aPart == null) return -1;
305 if (bPart == null) return 1;
306
307 if (aPart is num) {
308 if (bPart is num) {
309 // Compare two numbers.
310 return aPart.compareTo(bPart);
311 } else {
312 // Numbers come before strings.
313 return -1;
314 }
315 } else {
316 if (bPart is num) {
317 // Strings come after numbers.
318 return 1;
319 } else {
320 // Compare two strings.
321 return aPart.compareTo(bPart);
322 }
323 }
324 }
325
326 // The lists are entirely equal.
327 return 0;
328 }
329 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698