Fix a bug where we'd parse pre-release constraints as empty (#25)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 207ba29..0246edd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 1.3.6
+
+* Fix a bug where constraints that only allowed pre-release versions would be
+ parsed as empty constraints.
+
# 1.3.5
* Fix a bug where `VersionRange.intersect()` would return incorrect results for
diff --git a/lib/src/version_constraint.dart b/lib/src/version_constraint.dart
index 36bbd9a..670a928 100644
--- a/lib/src/version_constraint.dart
+++ b/lib/src/version_constraint.dart
@@ -57,7 +57,7 @@
if (text == "any") return any;
// Try to parse and consume a version number.
- matchVersion() {
+ Version matchVersion() {
var version = START_VERSION.firstMatch(text);
if (version == null) return null;
@@ -66,7 +66,7 @@
}
// Try to parse and consume a comparison operator followed by a version.
- matchComparison() {
+ VersionRange matchComparison() {
var comparison = START_COMPARISON.firstMatch(text);
if (comparison == null) return null;
@@ -117,35 +117,55 @@
var compatibleWith = matchCompatibleWith();
if (compatibleWith != null) return compatibleWith;
- var constraints = <VersionConstraint>[];
+ Version min;
+ var includeMin = false;
+ Version max;
+ var includeMax = false;
while (true) {
skipWhitespace();
if (text.isEmpty) break;
- var version = matchVersion();
- if (version != null) {
- constraints.add(version);
- continue;
+ var newRange = matchVersion() ?? matchComparison();
+ if (newRange == null) {
+ throw new FormatException('Could not parse version "$originalText". '
+ 'Unknown text at "$text".');
}
- var comparison = matchComparison();
- if (comparison != null) {
- constraints.add(comparison);
- continue;
+ if (newRange.min != null) {
+ if (min == null || newRange.min > min) {
+ min = newRange.min;
+ includeMin = newRange.includeMin;
+ } else if (newRange.min == min && !newRange.includeMin) {
+ includeMin = false;
+ }
}
- // If we got here, we couldn't parse the remaining string.
- throw new FormatException('Could not parse version "$originalText". '
- 'Unknown text at "$text".');
+ if (newRange.max != null) {
+ if (max == null || newRange.max < max) {
+ max = newRange.max;
+ includeMax = newRange.includeMax;
+ } else if (newRange.max == max && !newRange.includeMax) {
+ includeMax = false;
+ }
+ }
}
- if (constraints.isEmpty) {
+ if (min == null && max == null) {
throw new FormatException('Cannot parse an empty string.');
}
- return new VersionConstraint.intersection(constraints);
+ if (min != null && max != null) {
+ if (min > max) return VersionConstraint.empty;
+ if (min == max) {
+ if (includeMin && includeMax) return min;
+ return VersionConstraint.empty;
+ }
+ }
+
+ return new VersionRange(
+ min: min, includeMin: includeMin, max: max, includeMax: includeMax);
}
/// Creates a version constraint which allows all versions that are
diff --git a/pubspec.yaml b/pubspec.yaml
index 4dbabe4..1b0beb8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: pub_semver
-version: 1.3.5
+version: 1.3.6
author: Dart Team <misc@dartlang.org>
description: >
Versions and version constraints implementing pub's versioning policy. This
diff --git a/test/version_constraint_test.dart b/test/version_constraint_test.dart
index bc37832..bf3a018 100644
--- a/test/version_constraint_test.dart
+++ b/test/version_constraint_test.dart
@@ -103,6 +103,18 @@
new Version.parse('1.3.0'), new Version.parse('3.4.5')));
});
+ test('parses a pre-release-only constraint', () {
+ var constraint = new VersionConstraint.parse('>=1.0.0-dev.2 <1.0.0');
+ expect(
+ constraint,
+ allows(new Version.parse('1.0.0-dev.2'),
+ new Version.parse('1.0.0-dev.3')));
+ expect(
+ constraint,
+ doesNotAllow(
+ new Version.parse('1.0.0-dev.1'), new Version.parse('1.0.0')));
+ });
+
test('ignores whitespace around comparison operators', () {
var constraint = new VersionConstraint.parse(' >1.0.0>=1.2.3 < 1.3.0');