OLD | NEW |
---|---|
(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 | |
10 /// Constrains versions to a fall within a given range. | |
11 /// | |
12 /// If there is a minimum, then this only allows versions that are at that | |
13 /// minimum or greater. If there is a maximum, then only versions less than | |
14 /// that are allowed. In other words, this allows `>= min, < max`. | |
15 class VersionRange implements VersionConstraint { | |
16 final Version min; | |
17 final Version max; | |
18 final bool includeMin; | |
19 final bool includeMax; | |
nweiz
2014/09/25 22:52:02
Document these, especially what it means for [min]
Bob Nystrom
2014/09/26 19:41:07
Done.
| |
20 | |
21 VersionRange({this.min, this.max, | |
nweiz
2014/09/25 22:52:02
Document this.
Bob Nystrom
2014/09/26 19:41:07
Done.
| |
22 this.includeMin: false, this.includeMax: false}) { | |
23 if (min != null && max != null && min > max) { | |
nweiz
2014/09/25 22:52:02
Nit: short-circuit to save a line.
Bob Nystrom
2014/09/26 19:41:07
I would in most cases, but I think this is a bit e
| |
24 throw new ArgumentError( | |
25 'Minimum version ("$min") must be less than maximum ("$max").'); | |
26 } | |
27 } | |
28 | |
29 bool operator ==(other) { | |
30 if (other is! VersionRange) return false; | |
31 | |
32 return min == other.min && | |
33 max == other.max && | |
34 includeMin == other.includeMin && | |
35 includeMax == other.includeMax; | |
36 } | |
37 | |
38 bool get isEmpty => false; | |
39 | |
40 bool get isAny => min == null && max == null; | |
41 | |
42 /// Tests if [other] matches falls within this version range. | |
nweiz
2014/09/25 22:52:02
-"matches"
Bob Nystrom
2014/09/26 19:41:07
Done.
| |
43 bool allows(Version other) { | |
44 if (min != null) { | |
45 if (other < min) return false; | |
46 if (!includeMin && other == min) return false; | |
47 } | |
48 | |
49 if (max != null) { | |
50 if (other > max) return false; | |
51 if (!includeMax && other == max) return false; | |
52 | |
53 // If the max isn't itself a pre-release, don't allow any pre-release | |
54 // versions of the max. | |
55 // | |
56 // See: https://www.npmjs.org/doc/misc/semver.html | |
57 if (!includeMax && | |
58 !max.isPreRelease && other.isPreRelease && | |
59 other.major == max.major && other.minor == max.minor && | |
60 other.patch == max.patch) { | |
61 return false; | |
62 } | |
63 } | |
64 | |
65 return true; | |
66 } | |
67 | |
68 VersionConstraint intersect(VersionConstraint other) { | |
69 if (other.isEmpty) return other; | |
70 | |
71 // A range and a Version just yields the version if it's in the range. | |
72 if (other is Version) { | |
73 return allows(other) ? other : VersionConstraint.empty; | |
74 } | |
75 | |
76 if (other is VersionRange) { | |
77 // Intersect the two ranges. | |
78 var intersectMin = min; | |
79 var intersectIncludeMin = includeMin; | |
80 var intersectMax = max; | |
81 var intersectIncludeMax = includeMax; | |
82 | |
83 if (other.min == null) { | |
84 // Do nothing. | |
85 } else if (intersectMin == null || intersectMin < other.min) { | |
86 intersectMin = other.min; | |
87 intersectIncludeMin = other.includeMin; | |
88 } else if (intersectMin == other.min && !other.includeMin) { | |
89 // The edges are the same, but one is exclusive, make it exclusive. | |
90 intersectIncludeMin = false; | |
91 } | |
92 | |
93 if (other.max == null) { | |
94 // Do nothing. | |
95 } else if (intersectMax == null || intersectMax > other.max) { | |
96 intersectMax = other.max; | |
97 intersectIncludeMax = other.includeMax; | |
98 } else if (intersectMax == other.max && !other.includeMax) { | |
99 // The edges are the same, but one is exclusive, make it exclusive. | |
100 intersectIncludeMax = false; | |
101 } | |
102 | |
103 if (intersectMin == null && intersectMax == null) { | |
104 // Open range. | |
105 return new VersionRange(); | |
106 } | |
107 | |
108 // If the range is just a single version. | |
109 if (intersectMin == intersectMax) { | |
110 // If both ends are inclusive, allow that version. | |
111 if (intersectIncludeMin && intersectIncludeMax) return intersectMin; | |
112 | |
113 // Otherwise, no versions. | |
114 return VersionConstraint.empty; | |
115 } | |
116 | |
117 if (intersectMin != null && intersectMax != null && | |
118 intersectMin > intersectMax) { | |
119 // Non-overlapping ranges, so empty. | |
120 return VersionConstraint.empty; | |
121 } | |
122 | |
123 // If we got here, there is an actual range. | |
124 return new VersionRange(min: intersectMin, max: intersectMax, | |
125 includeMin: intersectIncludeMin, includeMax: intersectIncludeMax); | |
126 } | |
127 | |
128 throw new ArgumentError( | |
129 'Unknown VersionConstraint type $other.'); | |
130 } | |
131 | |
132 String toString() { | |
133 var buffer = new StringBuffer(); | |
134 | |
135 if (min != null) { | |
136 buffer.write(includeMin ? '>=' : '>'); | |
137 buffer.write(min); | |
138 } | |
139 | |
140 if (max != null) { | |
141 if (min != null) buffer.write(' '); | |
142 buffer.write(includeMax ? '<=' : '<'); | |
143 buffer.write(max); | |
144 } | |
145 | |
146 if (min == null && max == null) buffer.write('any'); | |
147 return buffer.toString(); | |
148 } | |
149 } | |
OLD | NEW |