codekingpro/portable-devtools
115k
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
6'use strict'
7
8const argv = process.argv.slice(2)
9
10let versions = []
11
12const range = []
13
14let inc = null
15
16const version = require('../package.json').version
17
18let loose = false
19
20let includePrerelease = false
21
22let coerce = false
23
24let rtl = false
25
26let identifier
27
28let identifierBase
29
30const semver = require('../')
31const parseOptions = require('../internal/parse-options')
32
33let reverse = false
34
35let options = {}
36
37const main = () => {
38 if (!argv.length) {
39 return help()
40 }
41 while (argv.length) {
42 let a = argv.shift()
43 const indexOfEqualSign = a.indexOf('=')
44 if (indexOfEqualSign !== -1) {
45 const value = a.slice(indexOfEqualSign + 1)
46 a = a.slice(0, indexOfEqualSign)
47 argv.unshift(value)
48 }
49 switch (a) {
50 case '-rv': case '-rev': case '--rev': case '--reverse':
51 reverse = true
52 break
53 case '-l': case '--loose':
54 loose = true
55 break
56 case '-p': case '--include-prerelease':
57 includePrerelease = true
58 break
59 case '-v': case '--version':
60 versions.push(argv.shift())
61 break
62 case '-i': case '--inc': case '--increment':
63 switch (argv[0]) {
64 case 'major': case 'minor': case 'patch': case 'prerelease':
65 case 'premajor': case 'preminor': case 'prepatch':
66 case 'release':
67 inc = argv.shift()
68 break
69 default:
70 inc = 'patch'
71 break
72 }
73 break
74 case '--preid':
75 identifier = argv.shift()
76 break
77 case '-r': case '--range':
78 range.push(argv.shift())
79 break
80 case '-n':
81 identifierBase = argv.shift()
82 if (identifierBase === 'false') {
83 identifierBase = false
84 }
85 break
86 case '-c': case '--coerce':
87 coerce = true
88 break
89 case '--rtl':
90 rtl = true
91 break
92 case '--ltr':
93 rtl = false
94 break
95 case '-h': case '--help': case '-?':
96 return help()
97 default:
98 versions.push(a)
99 break
100 }
101 }
102
103 options = parseOptions({ loose, includePrerelease, rtl })
104
105 versions = versions.map((v) => {
106 return coerce ? (semver.coerce(v, options) || { version: v }).version : v
107 }).filter((v) => {
108 return semver.valid(v, options)
109 })
110 if (!versions.length) {
111 return fail()
112 }
113 if (inc && (versions.length !== 1 || range.length)) {
114 return failInc()
115 }
116
117 for (let i = 0, l = range.length; i < l; i++) {
118 versions = versions.filter((v) => {
119 return semver.satisfies(v, range[i], options)
120 })
121 if (!versions.length) {
122 return fail()
123 }
124 }
125 versions
126 .sort((a, b) => semver[reverse ? 'rcompare' : 'compare'](a, b, options))
127 .map(v => semver.clean(v, options))
128 .map(v => inc ? semver.inc(v, inc, options, identifier, identifierBase) : v)
129 .forEach(v => console.log(v))
130}
131
132const failInc = () => {
133 console.error('--inc can only be used on a single version with no range')
134 fail()
135}
136
137const fail = () => process.exit(1)
138
139const help = () => console.log(
140`SemVer ${version}
141
142A JavaScript implementation of the https://semver.org/ specification
143Copyright Isaac Z. Schlueter
144
145Usage: semver [options] <version> [<version> [...]]
146Prints valid versions sorted by SemVer precedence
147
148Options:
149-r --range <range>
150 Print versions that match the specified range.
151
152-i --increment [<level>]
153 Increment a version by the specified level. Level can
154 be one of: major, minor, patch, premajor, preminor,
155 prepatch, prerelease, or release. Default level is 'patch'.
156 Only one version may be specified.
157
158--preid <identifier>
159 Identifier to be used to prefix premajor, preminor,
160 prepatch or prerelease version increments.
161
162-l --loose
163 Interpret versions and ranges loosely
164
165-p --include-prerelease
166 Always include prerelease versions in range matching
167
168-c --coerce
169 Coerce a string into SemVer if possible
170 (does not imply --loose)
171
172--rtl
173 Coerce version strings right to left
174
175--ltr
176 Coerce version strings left to right (default)
177
178-n <base>
179 Base number to be used for the prerelease identifier.
180 Can be either 0 or 1, or false to omit the number altogether.
181 Defaults to 0.
182
183Program exits successfully if any valid version satisfies
184all supplied ranges, and prints all satisfying versions.
185
186If no satisfying versions are found, then exits failure.
187
188Versions are printed in ascending order, so supplying
189multiple versions to the utility will just sort them.`)
190
191main()
192 