| 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 |