Skip to content

Commit

Permalink
Add semver.minVersion function.
Browse files Browse the repository at this point in the history
  • Loading branch information
coreyfarrell committed Jan 18, 2019
1 parent 6086e5a commit b99ae3b
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true
semver.minVersion('>=1.0.0') // '1.0.0'
semver.valid(semver.coerce('v2')) // '2.0.0'
semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'
```
Expand Down Expand Up @@ -368,6 +369,8 @@ strings that they parse.
that satisfies the range, or `null` if none of them do.
* `minSatisfying(versions, range)`: Return the lowest version in the list
that satisfies the range, or `null` if none of them do.
* `minVersion(range)`: Return the lowest version that can possibly match
the given range.
* `gtr(version, range)`: Return `true` if version is greater than all the
versions possible in the range.
* `ltr(version, range)`: Return `true` if version is less than all the
Expand Down
54 changes: 54 additions & 0 deletions semver.js
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,60 @@ function minSatisfying (versions, range, options) {
return min
}

exports.minVersion = minVersion
function minVersion (range, loose) {
range = new Range(range, loose)

var minver = new SemVer('0.0.0')
if (range.test(minver)) {
return minver
}

minver = new SemVer('0.0.0-0')
if (range.test(minver)) {
return minver
}

minver = null
for (var i = 0; i < range.set.length; ++i) {
var comparators = range.set[i]

comparators.forEach(function (comparator) {
// Clone to avoid manipulating the comparator's semver object.
var compver = new SemVer(comparator.semver.version)
switch (comparator.operator) {
case '>':
if (compver.prerelease.length === 0) {
compver.patch++
} else {
compver.prerelease.push(0)
}
compver.raw = compver.format()
/* fallthrough */
case '':
case '>=':
if (!minver || gt(minver, compver)) {
minver = compver
}
break
case '<':
case '<=':
/* Ignore maximum versions */
break
/* istanbul ignore next */
default:
throw new Error('Unexpected operation: ' + comparator.operator)
}
})
}

if (minver && range.test(minver)) {
return minver
}

return null
}

exports.validRange = validRange
function validRange (range, options) {
try {
Expand Down
76 changes: 76 additions & 0 deletions test/min-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
var tap = require('tap')
var test = tap.test
var semver = require('../semver.js')

test('\nminimum version in range tests', function (t) {
// [range, minimum, loose]
[
// Stars
['*', '0.0.0'],
['* || >=2', '0.0.0'],
['>=2 || *', '0.0.0'],
['>2 || *', '0.0.0'],

// equal
['1.0.0', '1.0.0'],
['1.0', '1.0.0'],
['1.0.x', '1.0.0'],
['1.0.*', '1.0.0'],
['1', '1.0.0'],
['1.x.x', '1.0.0'],
['1.x.x', '1.0.0'],
['1.*.x', '1.0.0'],
['1.x.*', '1.0.0'],
['1.x', '1.0.0'],
['1.*', '1.0.0'],
['=1.0.0', '1.0.0'],

// Tilde
['~1.1.1', '1.1.1'],
['~1.1.1-beta', '1.1.1-beta'],
['~1.1.1 || >=2', '1.1.1'],

// Carot
['^1.1.1', '1.1.1'],
['^1.1.1-beta', '1.1.1-beta'],
['^1.1.1 || >=2', '1.1.1'],

// '-' operator
['1.1.1 - 1.8.0', '1.1.1'],
['1.1 - 1.8.0', '1.1.0'],

// Less / less or equal
['<2', '0.0.0'],
['<0.0.0-beta', '0.0.0-0'],
['<0.0.1-beta', '0.0.0'],
['<2 || >4', '0.0.0'],
['>4 || <2', '0.0.0'],
['<=2 || >=4', '0.0.0'],
['>=4 || <=2', '0.0.0'],
['<0.0.0-beta >0.0.0-alpha', '0.0.0-alpha.0'],
['>0.0.0-alpha <0.0.0-beta', '0.0.0-alpha.0'],

// Greater than or equal
['>=1.1.1 <2 || >=2.2.2 <2', '1.1.1'],
['>=2.2.2 <2 || >=1.1.1 <2', '1.1.1'],

// Greater than but not equal
['>1.0.0', '1.0.1'],
['>1.0.0-0', '1.0.0-0.0'],
['>1.0.0-beta', '1.0.0-beta.0'],
['>2 || >1.0.0', '1.0.1'],
['>2 || >1.0.0-0', '1.0.0-0.0'],
['>2 || >1.0.0-beta', '1.0.0-beta.0'],

// Impossible range
['>4 <3', null]
].forEach(function (tuple) {
var range = tuple[0]
var version = tuple[1]
var loose = tuple[2] || false
var msg = 'minVersion(' + range + ', ' + loose + ') = ' + version
var min = semver.minVersion(range, loose)
t.ok(min === version || (min && min.version === version), msg)
})
t.end()
})

0 comments on commit b99ae3b

Please sign in to comment.