• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env node
2// Standalone semver comparison program.
3// Exits successfully and prints matching version(s) if
4// any supplied version is valid and passes all tests.
5
6var argv = process.argv.slice(2)
7
8var versions = []
9
10var range = []
11
12var inc = null
13
14var version = require('../package.json').version
15
16var loose = false
17
18var includePrerelease = false
19
20var coerce = false
21
22var identifier
23
24var semver = require('../semver')
25
26var reverse = false
27
28var options = {}
29
30main()
31
32function main () {
33  if (!argv.length) return help()
34  while (argv.length) {
35    var a = argv.shift()
36    var indexOfEqualSign = a.indexOf('=')
37    if (indexOfEqualSign !== -1) {
38      a = a.slice(0, indexOfEqualSign)
39      argv.unshift(a.slice(indexOfEqualSign + 1))
40    }
41    switch (a) {
42      case '-rv': case '-rev': case '--rev': case '--reverse':
43        reverse = true
44        break
45      case '-l': case '--loose':
46        loose = true
47        break
48      case '-p': case '--include-prerelease':
49        includePrerelease = true
50        break
51      case '-v': case '--version':
52        versions.push(argv.shift())
53        break
54      case '-i': case '--inc': case '--increment':
55        switch (argv[0]) {
56          case 'major': case 'minor': case 'patch': case 'prerelease':
57          case 'premajor': case 'preminor': case 'prepatch':
58            inc = argv.shift()
59            break
60          default:
61            inc = 'patch'
62            break
63        }
64        break
65      case '--preid':
66        identifier = argv.shift()
67        break
68      case '-r': case '--range':
69        range.push(argv.shift())
70        break
71      case '-c': case '--coerce':
72        coerce = true
73        break
74      case '-h': case '--help': case '-?':
75        return help()
76      default:
77        versions.push(a)
78        break
79    }
80  }
81
82  var options = { loose: loose, includePrerelease: includePrerelease }
83
84  versions = versions.map(function (v) {
85    return coerce ? (semver.coerce(v) || { version: v }).version : v
86  }).filter(function (v) {
87    return semver.valid(v)
88  })
89  if (!versions.length) return fail()
90  if (inc && (versions.length !== 1 || range.length)) { return failInc() }
91
92  for (var i = 0, l = range.length; i < l; i++) {
93    versions = versions.filter(function (v) {
94      return semver.satisfies(v, range[i], options)
95    })
96    if (!versions.length) return fail()
97  }
98  return success(versions)
99}
100
101function failInc () {
102  console.error('--inc can only be used on a single version with no range')
103  fail()
104}
105
106function fail () { process.exit(1) }
107
108function success () {
109  var compare = reverse ? 'rcompare' : 'compare'
110  versions.sort(function (a, b) {
111    return semver[compare](a, b, options)
112  }).map(function (v) {
113    return semver.clean(v, options)
114  }).map(function (v) {
115    return inc ? semver.inc(v, inc, options, identifier) : v
116  }).forEach(function (v, i, _) { console.log(v) })
117}
118
119function help () {
120  console.log(['SemVer ' + version,
121    '',
122    'A JavaScript implementation of the https://semver.org/ specification',
123    'Copyright Isaac Z. Schlueter',
124    '',
125    'Usage: semver [options] <version> [<version> [...]]',
126    'Prints valid versions sorted by SemVer precedence',
127    '',
128    'Options:',
129    '-r --range <range>',
130    '        Print versions that match the specified range.',
131    '',
132    '-i --increment [<level>]',
133    '        Increment a version by the specified level.  Level can',
134    '        be one of: major, minor, patch, premajor, preminor,',
135    "        prepatch, or prerelease.  Default level is 'patch'.",
136    '        Only one version may be specified.',
137    '',
138    '--preid <identifier>',
139    '        Identifier to be used to prefix premajor, preminor,',
140    '        prepatch or prerelease version increments.',
141    '',
142    '-l --loose',
143    '        Interpret versions and ranges loosely',
144    '',
145    '-p --include-prerelease',
146    '        Always include prerelease versions in range matching',
147    '',
148    '-c --coerce',
149    '        Coerce a string into SemVer if possible',
150    '        (does not imply --loose)',
151    '',
152    'Program exits successfully if any valid version satisfies',
153    'all supplied ranges, and prints all satisfying versions.',
154    '',
155    'If no satisfying versions are found, then exits failure.',
156    '',
157    'Versions are printed in ascending order, so supplying',
158    'multiple versions to the utility will just sort them.'
159  ].join('\n'))
160}
161