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 /// Handles version numbers, following the [Semantic Versioning][semver] spec. | 5 /// Handles version numbers, following the [Semantic Versioning][semver] spec. |
6 /// | 6 /// |
7 /// [semver]: http://semver.org/ | 7 /// [semver]: http://semver.org/ |
8 library version; | 8 library version; |
9 | 9 |
10 import 'dart:math'; | 10 import 'dart:math'; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 /// Tests if [other] matches this version exactly. | 103 /// Tests if [other] matches this version exactly. |
104 bool allows(Version other) => this == other; | 104 bool allows(Version other) => this == other; |
105 | 105 |
106 VersionConstraint intersect(VersionConstraint other) { | 106 VersionConstraint intersect(VersionConstraint other) { |
107 if (other.isEmpty) return other; | 107 if (other.isEmpty) return other; |
108 | 108 |
109 // Intersect a version and a range. | 109 // Intersect a version and a range. |
110 if (other is VersionRange) return other.intersect(this); | 110 if (other is VersionRange) return other.intersect(this); |
111 | 111 |
112 // Intersecting two versions only works if they are the same. | 112 // Intersecting two versions only works if they are the same. |
113 if (other is Version) return this == other ? this : const _EmptyVersion(); | 113 if (other is Version) { |
| 114 return this == other ? this : VersionConstraint.empty; |
| 115 } |
114 | 116 |
115 throw new ArgumentError( | 117 throw new ArgumentError( |
116 'Unknown VersionConstraint type $other.'); | 118 'Unknown VersionConstraint type $other.'); |
117 } | 119 } |
118 | 120 |
119 int compareTo(Version other) { | 121 int compareTo(Version other) { |
120 if (major != other.major) return major.compareTo(other.major); | 122 if (major != other.major) return major.compareTo(other.major); |
121 if (minor != other.minor) return minor.compareTo(other.minor); | 123 if (minor != other.minor) return minor.compareTo(other.minor); |
122 if (patch != other.patch) return patch.compareTo(other.patch); | 124 if (patch != other.patch) return patch.compareTo(other.patch); |
123 | 125 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 } | 201 } |
200 }).toList(); | 202 }).toList(); |
201 } | 203 } |
202 } | 204 } |
203 | 205 |
204 /// A [VersionConstraint] is a predicate that can determine whether a given | 206 /// A [VersionConstraint] is a predicate that can determine whether a given |
205 /// version is valid or not. For example, a ">= 2.0.0" constraint allows any | 207 /// version is valid or not. For example, a ">= 2.0.0" constraint allows any |
206 /// version that is "2.0.0" or greater. Version objects themselves implement | 208 /// version that is "2.0.0" or greater. Version objects themselves implement |
207 /// this to match a specific version. | 209 /// this to match a specific version. |
208 abstract class VersionConstraint { | 210 abstract class VersionConstraint { |
| 211 /// A [VersionConstraint] that allows all versions. |
| 212 static VersionConstraint any = new VersionRange(); |
| 213 |
209 /// A [VersionConstraint] that allows no versions: i.e. the empty set. | 214 /// A [VersionConstraint] that allows no versions: i.e. the empty set. |
210 factory VersionConstraint.empty() => const _EmptyVersion(); | 215 static VersionConstraint empty = const _EmptyVersion(); |
211 | 216 |
212 /// Parses a version constraint. This string is a space-separated series of | 217 /// Parses a version constraint. This string is a space-separated series of |
213 /// version parts. Each part can be one of: | 218 /// version parts. Each part can be one of: |
214 /// | 219 /// |
215 /// * A version string like `1.2.3`. In other words, anything that can be | 220 /// * A version string like `1.2.3`. In other words, anything that can be |
216 /// parsed by [Version.parse()]. | 221 /// parsed by [Version.parse()]. |
217 /// * A comparison operator (`<`, `>`, `<=`, or `>=`) followed by a version | 222 /// * A comparison operator (`<`, `>`, `<=`, or `>=`) followed by a version |
218 /// string. There cannot be a space between the operator and the version. | 223 /// string. There cannot be a space between the operator and the version. |
219 /// | 224 /// |
220 /// Examples: | 225 /// Examples: |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 if (min != null && !includeMin && other == min) return false; | 331 if (min != null && !includeMin && other == min) return false; |
327 if (max != null && other > max) return false; | 332 if (max != null && other > max) return false; |
328 if (max != null && !includeMax && other == max) return false; | 333 if (max != null && !includeMax && other == max) return false; |
329 return true; | 334 return true; |
330 } | 335 } |
331 | 336 |
332 VersionConstraint intersect(VersionConstraint other) { | 337 VersionConstraint intersect(VersionConstraint other) { |
333 if (other.isEmpty) return other; | 338 if (other.isEmpty) return other; |
334 | 339 |
335 // A range and a Version just yields the version if it's in the range. | 340 // A range and a Version just yields the version if it's in the range. |
336 if (other is Version) return allows(other) ? other : const _EmptyVersion(); | 341 if (other is Version) { |
| 342 return allows(other) ? other : VersionConstraint.empty; |
| 343 } |
337 | 344 |
338 if (other is VersionRange) { | 345 if (other is VersionRange) { |
339 // Intersect the two ranges. | 346 // Intersect the two ranges. |
340 var intersectMin = min; | 347 var intersectMin = min; |
341 var intersectIncludeMin = includeMin; | 348 var intersectIncludeMin = includeMin; |
342 var intersectMax = max; | 349 var intersectMax = max; |
343 var intersectIncludeMax = includeMax; | 350 var intersectIncludeMax = includeMax; |
344 | 351 |
345 if (other.min == null) { | 352 if (other.min == null) { |
346 // Do nothing. | 353 // Do nothing. |
(...skipping 19 matching lines...) Expand all Loading... |
366 // Open range. | 373 // Open range. |
367 return new VersionRange(); | 374 return new VersionRange(); |
368 } | 375 } |
369 | 376 |
370 // If the range is just a single version. | 377 // If the range is just a single version. |
371 if (intersectMin == intersectMax) { | 378 if (intersectMin == intersectMax) { |
372 // If both ends are inclusive, allow that version. | 379 // If both ends are inclusive, allow that version. |
373 if (intersectIncludeMin && intersectIncludeMax) return intersectMin; | 380 if (intersectIncludeMin && intersectIncludeMax) return intersectMin; |
374 | 381 |
375 // Otherwise, no versions. | 382 // Otherwise, no versions. |
376 return const _EmptyVersion(); | 383 return VersionConstraint.empty; |
377 } | 384 } |
378 | 385 |
379 if (intersectMin != null && intersectMax != null && | 386 if (intersectMin != null && intersectMax != null && |
380 intersectMin > intersectMax) { | 387 intersectMin > intersectMax) { |
381 // Non-overlapping ranges, so empty. | 388 // Non-overlapping ranges, so empty. |
382 return const _EmptyVersion(); | 389 return VersionConstraint.empty; |
383 } | 390 } |
384 | 391 |
385 // If we got here, there is an actual range. | 392 // If we got here, there is an actual range. |
386 return new VersionRange(min: intersectMin, max: intersectMax, | 393 return new VersionRange(min: intersectMin, max: intersectMax, |
387 includeMin: intersectIncludeMin, includeMax: intersectIncludeMax); | 394 includeMin: intersectIncludeMin, includeMax: intersectIncludeMax); |
388 } | 395 } |
389 | 396 |
390 throw new ArgumentError( | 397 throw new ArgumentError( |
391 'Unknown VersionConstraint type $other.'); | 398 'Unknown VersionConstraint type $other.'); |
392 } | 399 } |
(...skipping 19 matching lines...) Expand all Loading... |
412 | 419 |
413 class _EmptyVersion implements VersionConstraint { | 420 class _EmptyVersion implements VersionConstraint { |
414 const _EmptyVersion(); | 421 const _EmptyVersion(); |
415 | 422 |
416 bool get isEmpty => true; | 423 bool get isEmpty => true; |
417 bool get isAny => false; | 424 bool get isAny => false; |
418 bool allows(Version other) => false; | 425 bool allows(Version other) => false; |
419 VersionConstraint intersect(VersionConstraint other) => this; | 426 VersionConstraint intersect(VersionConstraint other) => this; |
420 String toString() => '<empty>'; | 427 String toString() => '<empty>'; |
421 } | 428 } |
OLD | NEW |