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

Unified 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: Revise! Created 6 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/src/version.dart ('k') | lib/src/version_range.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/version_constraint.dart
diff --git a/lib/src/version_constraint.dart b/lib/src/version_constraint.dart
new file mode 100644
index 0000000000000000000000000000000000000000..ed85827cb8cab849c0cfbeaa91d92a82cca96dda
--- /dev/null
+++ b/lib/src/version_constraint.dart
@@ -0,0 +1,151 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_semver.src.version_constraint;
+
+import 'patterns.dart';
+import 'version.dart';
+import 'version_range.dart';
+
+/// A [VersionConstraint] is a predicate that can determine whether a given
+/// version is valid or not.
+///
+/// For example, a ">= 2.0.0" constraint allows any version that is "2.0.0" or
+/// greater. Version objects themselves implement this to match a specific
+/// version.
+abstract class VersionConstraint {
+ /// A [VersionConstraint] that allows all versions.
+ static VersionConstraint any = new VersionRange();
+
+ /// A [VersionConstraint] that allows no versions -- the empty set.
+ static VersionConstraint empty = const _EmptyVersion();
+
+ /// Parses a version constraint.
+ ///
+ /// This string is either "any" or a series of version parts. Each part can
+ /// be one of:
+ ///
+ /// * A version string like `1.2.3`. In other words, anything that can be
+ /// parsed by [Version.parse()].
+ /// * A comparison operator (`<`, `>`, `<=`, or `>=`) followed by a version
+ /// string.
+ ///
+ /// Whitespace is ignored.
+ ///
+ /// Examples:
+ ///
+ /// any
+ /// 1.2.3-alpha
+ /// <=5.1.4
+ /// >2.0.4 <= 2.4.6
+ factory VersionConstraint.parse(String text) {
+ // Handle the "any" constraint.
+ if (text.trim() == "any") return new VersionRange();
+
+ var originalText = text;
+ var constraints = <VersionConstraint>[];
+
+ skipWhitespace() {
+ text = text.trim();
+ }
+
+ // Try to parse and consume a version number.
+ matchVersion() {
+ var version = START_VERSION.firstMatch(text);
+ if (version == null) return null;
+
+ text = text.substring(version.end);
+ return new Version.parse(version[0]);
+ }
+
+ // Try to parse and consume a comparison operator followed by a version.
+ matchComparison() {
+ var comparison = START_COMPARISON.firstMatch(text);
+ if (comparison == null) return null;
+
+ var op = comparison[0];
+ text = text.substring(comparison.end);
+ skipWhitespace();
+
+ var version = matchVersion();
+ if (version == null) {
+ throw new FormatException('Expected version number after "$op" in '
+ '"$originalText", got "$text".');
+ }
+
+ switch (op) {
+ case '<=': return new VersionRange(max: version, includeMax: true);
+ case '<': return new VersionRange(max: version, includeMax: false);
+ case '>=': return new VersionRange(min: version, includeMin: true);
+ case '>': return new VersionRange(min: version, includeMin: false);
+ }
+ throw "Unreachable.";
+ }
+
+ while (true) {
+ skipWhitespace();
+ if (text.isEmpty) break;
+
+ var version = matchVersion();
+ if (version != null) {
+ constraints.add(version);
+ continue;
+ }
+
+ var comparison = matchComparison();
+ if (comparison != null) {
+ constraints.add(comparison);
+ continue;
+ }
+
+ // If we got here, we couldn't parse the remaining string.
+ throw new FormatException('Could not parse version "$originalText". '
+ 'Unknown text at "$text".');
+ }
+
+ if (constraints.isEmpty) {
+ throw new FormatException('Cannot parse an empty string.');
+ }
+
+ return new VersionConstraint.intersection(constraints);
+ }
+
+ /// Creates a new version constraint that is the intersection of
+ /// [constraints].
+ ///
+ /// It only allows versions that all of those constraints allow. If
+ /// constraints is empty, then it returns a VersionConstraint that allows
+ /// all versions.
+ factory VersionConstraint.intersection(
+ Iterable<VersionConstraint> constraints) {
+ var constraint = new VersionRange();
+ for (var other in constraints) {
+ constraint = constraint.intersect(other);
+ }
+ return constraint;
+ }
+
+ /// Returns `true` if this constraint allows no versions.
+ bool get isEmpty;
+
+ /// Returns `true` if this constraint allows all versions.
+ bool get isAny;
+
+ /// Returns `true` if this constraint allows [version].
+ bool allows(Version version);
+
+ /// Creates a new [VersionConstraint] that only allows [Version]s allowed by
+ /// both this and [other].
+ VersionConstraint intersect(VersionConstraint other);
+}
+
+class _EmptyVersion implements VersionConstraint {
+ const _EmptyVersion();
+
+ bool get isEmpty => true;
+ bool get isAny => false;
+ bool allows(Version other) => false;
+ VersionConstraint intersect(VersionConstraint other) => this;
+ String toString() => '<empty>';
+}
« no previous file with comments | « lib/src/version.dart ('k') | lib/src/version_range.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698