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

Side by Side Diff: lib/src/version.dart

Issue 1127783002: Add more set-like version constraint operations. (Closed) Base URL: git@github.com:dart-lang/pub_semver@master
Patch Set: Code review changes Created 5 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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 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 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 pub_semver.src.version; 5 library pub_semver.src.version;
6 6
7 import 'dart:math'; 7 import 'dart:math' as math;
8 8
9 import 'package:collection/equality.dart'; 9 import 'package:collection/equality.dart';
10 10
11 import 'patterns.dart'; 11 import 'patterns.dart';
12 import 'version_constraint.dart'; 12 import 'version_constraint.dart';
13 import 'version_range.dart'; 13 import 'version_range.dart';
14 14
15 /// The equality operator to use for comparing version components. 15 /// The equality operator to use for comparing version components.
16 final _equality = const IterableEquality(); 16 final _equality = const IterableEquality();
17 17
18 /// A parsed semantic version number. 18 /// A parsed semantic version number.
19 class Version implements Comparable<Version>, VersionConstraint { 19 class Version implements Comparable<Version>, VersionConstraint, VersionRange {
20 /// No released version: i.e. "0.0.0". 20 /// No released version: i.e. "0.0.0".
21 static Version get none => new Version(0, 0, 0); 21 static Version get none => new Version(0, 0, 0);
22 22
23 /// Compares [a] and [b] to see which takes priority over the other. 23 /// Compares [a] and [b] to see which takes priority over the other.
24 /// 24 ///
25 /// Returns `1` if [a] takes priority over [b] and `-1` if vice versa. If 25 /// Returns `1` if [a] takes priority over [b] and `-1` if vice versa. If
26 /// [a] and [b] are equivalent, returns `0`. 26 /// [a] and [b] are equivalent, returns `0`.
27 /// 27 ///
28 /// Unlike [compareTo], which *orders* versions, this determines which 28 /// Unlike [compareTo], which *orders* versions, this determines which
29 /// version a user is likely to prefer. In particular, it prioritizes 29 /// version a user is likely to prefer. In particular, it prioritizes
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 /// string or a non-negative integer. It may also be empty, indicating that 78 /// string or a non-negative integer. It may also be empty, indicating that
79 /// this version has no build identifier. 79 /// this version has no build identifier.
80 final List build; 80 final List build;
81 81
82 /// The original string representation of the version number. 82 /// The original string representation of the version number.
83 /// 83 ///
84 /// This preserves textual artifacts like leading zeros that may be left out 84 /// This preserves textual artifacts like leading zeros that may be left out
85 /// of the parsed version. 85 /// of the parsed version.
86 final String _text; 86 final String _text;
87 87
88 Version get min => this;
89 Version get max => this;
90 bool get includeMin => true;
91 bool get includeMax => true;
92
88 Version._(this.major, this.minor, this.patch, String preRelease, String build, 93 Version._(this.major, this.minor, this.patch, String preRelease, String build,
89 this._text) 94 this._text)
90 : preRelease = preRelease == null ? [] : _splitParts(preRelease), 95 : preRelease = preRelease == null ? [] : _splitParts(preRelease),
91 build = build == null ? [] : _splitParts(build) { 96 build = build == null ? [] : _splitParts(build) {
92 if (major < 0) throw new ArgumentError( 97 if (major < 0) throw new ArgumentError(
93 'Major version must be non-negative.'); 98 'Major version must be non-negative.');
94 if (minor < 0) throw new ArgumentError( 99 if (minor < 0) throw new ArgumentError(
95 'Minor version must be non-negative.'); 100 'Minor version must be non-negative.');
96 if (patch < 0) throw new ArgumentError( 101 if (patch < 0) throw new ArgumentError(
97 'Patch version must be non-negative.'); 102 'Patch version must be non-negative.');
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 return _incrementMajor(); 235 return _incrementMajor();
231 } 236 }
232 237
233 Version _incrementMajor() => new Version(major + 1, 0, 0); 238 Version _incrementMajor() => new Version(major + 1, 0, 0);
234 Version _incrementMinor() => new Version(major, minor + 1, 0); 239 Version _incrementMinor() => new Version(major, minor + 1, 0);
235 Version _incrementPatch() => new Version(major, minor, patch + 1); 240 Version _incrementPatch() => new Version(major, minor, patch + 1);
236 241
237 /// Tests if [other] matches this version exactly. 242 /// Tests if [other] matches this version exactly.
238 bool allows(Version other) => this == other; 243 bool allows(Version other) => this == other;
239 244
240 VersionConstraint intersect(VersionConstraint other) { 245 bool allowsAll(VersionConstraint other) => other.isEmpty || other == this;
241 if (other.isEmpty) return other;
242 246
243 // Intersect a version and a range. 247 bool allowsAny(VersionConstraint other) => other.allows(this);
244 if (other is VersionRange) return other.intersect(this);
245 248
246 // Intersecting two versions only works if they are the same. 249 VersionConstraint intersect(VersionConstraint other) =>
247 if (other is Version) { 250 other.allows(this) ? this : VersionConstraint.empty;
248 return this == other ? 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 }
249 } 267 }
250 268
251 throw new ArgumentError( 269 return new VersionConstraint.unionOf([this, other]);
252 'Unknown VersionConstraint type $other.');
253 } 270 }
254 271
255 int compareTo(Version other) { 272 int compareTo(Version other) {
256 if (major != other.major) return major.compareTo(other.major); 273 if (major != other.major) return major.compareTo(other.major);
257 if (minor != other.minor) return minor.compareTo(other.minor); 274 if (minor != other.minor) return minor.compareTo(other.minor);
258 if (patch != other.patch) return patch.compareTo(other.patch); 275 if (patch != other.patch) return patch.compareTo(other.patch);
259 276
260 // Pre-releases always come before no pre-release string. 277 // Pre-releases always come before no pre-release string.
261 if (!isPreRelease && other.isPreRelease) return 1; 278 if (!isPreRelease && other.isPreRelease) return 1;
262 if (!other.isPreRelease && isPreRelease) return -1; 279 if (!other.isPreRelease && isPreRelease) return -1;
263 280
264 var comparison = _compareLists(preRelease, other.preRelease); 281 var comparison = _compareLists(preRelease, other.preRelease);
265 if (comparison != 0) return comparison; 282 if (comparison != 0) return comparison;
266 283
267 // Builds always come after no build string. 284 // Builds always come after no build string.
268 if (build.isEmpty && other.build.isNotEmpty) return -1; 285 if (build.isEmpty && other.build.isNotEmpty) return -1;
269 if (other.build.isEmpty && build.isNotEmpty) return 1; 286 if (other.build.isEmpty && build.isNotEmpty) return 1;
270 return _compareLists(build, other.build); 287 return _compareLists(build, other.build);
271 } 288 }
272 289
273 String toString() => _text; 290 String toString() => _text;
274 291
275 /// Compares a dot-separated component of two versions. 292 /// Compares a dot-separated component of two versions.
276 /// 293 ///
277 /// This is used for the pre-release and build version parts. This follows 294 /// This is used for the pre-release and build version parts. This follows
278 /// Rule 12 of the Semantic Versioning spec (v2.0.0-rc.1). 295 /// Rule 12 of the Semantic Versioning spec (v2.0.0-rc.1).
279 int _compareLists(List a, List b) { 296 int _compareLists(List a, List b) {
280 for (var i = 0; i < max(a.length, b.length); i++) { 297 for (var i = 0; i < math.max(a.length, b.length); i++) {
281 var aPart = (i < a.length) ? a[i] : null; 298 var aPart = (i < a.length) ? a[i] : null;
282 var bPart = (i < b.length) ? b[i] : null; 299 var bPart = (i < b.length) ? b[i] : null;
283 300
284 if (aPart == bPart) continue; 301 if (aPart == bPart) continue;
285 302
286 // Missing parts come before present ones. 303 // Missing parts come before present ones.
287 if (aPart == null) return -1; 304 if (aPart == null) return -1;
288 if (bPart == null) return 1; 305 if (bPart == null) return 1;
289 306
290 if (aPart is num) { 307 if (aPart is num) {
(...skipping 12 matching lines...) Expand all
303 // Compare two strings. 320 // Compare two strings.
304 return aPart.compareTo(bPart); 321 return aPart.compareTo(bPart);
305 } 322 }
306 } 323 }
307 } 324 }
308 325
309 // The lists are entirely equal. 326 // The lists are entirely equal.
310 return 0; 327 return 0;
311 } 328 }
312 } 329 }
OLDNEW
« no previous file with comments | « lib/src/utils.dart ('k') | lib/src/version_constraint.dart » ('j') | lib/src/version_range.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698