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

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

Issue 607663002: Harvest from pub. Mostly a straight copy, except: (Closed) Base URL: https://github.com/dart-lang/pub_semver.git@master
Patch Set: Created 6 years, 2 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_constraint;
6
7 import 'patterns.dart';
8 import 'version.dart';
9 import 'version_range.dart';
10
11 /// A [VersionConstraint] is a predicate that can determine whether a given
12 /// version is valid or not.
13 ///
14 /// For example, a ">= 2.0.0" constraint allows any version that is "2.0.0" or
15 /// greater. Version objects themselves implement this to match a specific
16 /// version.
17 abstract class VersionConstraint {
18 /// A [VersionConstraint] that allows all versions.
19 static VersionConstraint any = new VersionRange();
20
21 /// A [VersionConstraint] that allows no versions: i.e. the empty set.
nweiz 2014/09/25 22:52:02 I think we're supposed to avoid "i.e." in docs.
Bob Nystrom 2014/09/26 19:41:07 Done.
22 static VersionConstraint empty = const _EmptyVersion();
23
24 /// Parses a version constraint.
25 ///
26 /// This string is either "any" or a series of version parts. Each part can
27 /// be one of:
28 ///
29 /// * A version string like `1.2.3`. In other words, anything that can be
30 /// parsed by [Version.parse()].
31 /// * A comparison operator (`<`, `>`, `<=`, or `>=`) followed by a version
32 /// string.
33 ///
34 /// Whitespace is ignored.
35 ///
36 /// Examples:
37 ///
38 /// any
39 /// 1.2.3-alpha
40 /// <=5.1.4
41 /// >2.0.4 <= 2.4.6
42 factory VersionConstraint.parse(String text) {
43 // Handle the "any" constraint.
44 if (text.trim() == "any") return new VersionRange();
45
46 var originalText = text;
47 var constraints = <VersionConstraint>[];
nweiz 2014/09/25 22:52:02 Nit: no type annotations here or for the functions
Bob Nystrom 2014/09/26 19:41:07 Done.
nweiz 2014/09/26 19:44:23 This array still has an annotation.
Bob Nystrom 2014/11/10 22:14:06 Done.
48
49 void skipWhitespace() {
50 text = text.trim();
51 }
52
53 // Try to parse and consume a version number.
54 Version matchVersion() {
55 var version = START_VERSION.firstMatch(text);
56 if (version == null) return null;
57
58 text = text.substring(version.end);
59 return new Version.parse(version[0]);
60 }
61
62 // Try to parse and consume a comparison operator followed by a version.
63 VersionConstraint matchComparison() {
64 var comparison = START_COMPARISON.firstMatch(text);
65 if (comparison == null) return null;
66
67 var op = comparison[0];
68 text = text.substring(comparison.end);
69 skipWhitespace();
70
71 var version = matchVersion();
72 if (version == null) {
73 throw new FormatException('Expected version number after "$op" in '
74 '"$originalText", got "$text".');
75 }
76
77 switch (op) {
78 case '<=': return new VersionRange(max: version, includeMax: true);
79 case '<': return new VersionRange(max: version, includeMax: false);
80 case '>=': return new VersionRange(min: version, includeMin: true);
81 case '>': return new VersionRange(min: version, includeMin: false);
82 }
83 throw "Unreachable.";
84 }
85
86 while (true) {
87 skipWhitespace();
88 if (text.isEmpty) break;
89
90 var version = matchVersion();
91 if (version != null) {
92 constraints.add(version);
93 continue;
94 }
95
96 var comparison = matchComparison();
97 if (comparison != null) {
98 constraints.add(comparison);
99 continue;
100 }
101
102 // If we got here, we couldn't parse the remaining string.
103 throw new FormatException('Could not parse version "$originalText". '
104 'Unknown text at "$text".');
105 }
106
107 if (constraints.isEmpty) {
108 throw new FormatException('Cannot parse an empty string.');
109 }
110
111 return new VersionConstraint.intersection(constraints);
112 }
113
114 /// Creates a new version constraint that is the intersection of
115 /// [constraints].
116 ///
117 /// It only allows versions that all of those constraints allow. If
118 /// constraints is empty, then it returns a VersionConstraint that allows
119 /// all versions.
120 factory VersionConstraint.intersection(
121 Iterable<VersionConstraint> constraints) {
122 var constraint = new VersionRange();
123 for (var other in constraints) {
124 constraint = constraint.intersect(other);
125 }
126 return constraint;
127 }
128
129 /// Returns `true` if this constraint allows no versions.
130 bool get isEmpty;
131
132 /// Returns `true` if this constraint allows all versions.
133 bool get isAny;
134
135 /// Returns `true` if this constraint allows [version].
136 bool allows(Version version);
137
138 /// Creates a new [VersionConstraint] that only allows [Version]s allowed by
139 /// both this and [other].
140 VersionConstraint intersect(VersionConstraint other);
141 }
142
143 class _EmptyVersion implements VersionConstraint {
144 const _EmptyVersion();
145
146 bool get isEmpty => true;
147 bool get isAny => false;
148 bool allows(Version other) => false;
149 VersionConstraint intersect(VersionConstraint other) => this;
150 String toString() => '<empty>';
151 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698