Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: identifierBase parameter for .inc #532

Merged
merged 1 commit into from Apr 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions README.md
Expand Up @@ -110,6 +110,9 @@ Options:
-l --loose
Interpret versions and ranges loosely

-n <0|1>
This is the base to be used for the prerelease identifier.

-p --include-prerelease
Always include prerelease versions in range matching

Expand Down Expand Up @@ -232,6 +235,24 @@ $ semver 1.2.4-beta.0 -i prerelease
1.2.4-beta.1
```

#### Prerelease Identifier Base

The method `.inc` takes an optional parameter 'identifierBase' string
that will let you let your prerelease number as zero-based or one-based.
If you do not specify this parameter, it will default to zero-based.

```javascript
semver.inc('1.2.3', 'prerelease', 'beta', '1')
// '1.2.4-beta.1'
```

command-line example:

```bash
$ semver 1.2.3 -i prerelease --preid beta -n 1
1.2.4-beta.1
```

### Advanced Range Syntax

Advanced range syntax desugars to primitive comparators in
Expand Down
7 changes: 6 additions & 1 deletion bin/semver.js
Expand Up @@ -23,6 +23,8 @@ let rtl = false

let identifier

let identifierBase

const semver = require('../')

let reverse = false
Expand Down Expand Up @@ -71,6 +73,9 @@ const main = () => {
case '-r': case '--range':
range.push(argv.shift())
break
case '-n':
identifierBase = argv.shift()
break
case '-c': case '--coerce':
coerce = true
break
Expand Down Expand Up @@ -127,7 +132,7 @@ const success = () => {
}).map((v) => {
return semver.clean(v, options)
}).map((v) => {
return inc ? semver.inc(v, inc, options, identifier) : v
return inc ? semver.inc(v, inc, options, identifier, identifierBase) : v
}).forEach((v, i, _) => {
console.log(v)
})
Expand Down
19 changes: 10 additions & 9 deletions classes/semver.js
Expand Up @@ -175,36 +175,36 @@ class SemVer {

// preminor will bump the version up to the next minor release, and immediately
// down to pre-release. premajor and prepatch work the same way.
inc (release, identifier) {
inc (release, identifier, identifierBase) {
switch (release) {
case 'premajor':
this.prerelease.length = 0
this.patch = 0
this.minor = 0
this.major++
this.inc('pre', identifier)
this.inc('pre', identifier, identifierBase)
break
case 'preminor':
this.prerelease.length = 0
this.patch = 0
this.minor++
this.inc('pre', identifier)
this.inc('pre', identifier, identifierBase)
break
case 'prepatch':
// If this is already a prerelease, it will bump to the next version
// drop any prereleases that might already exist, since they are not
// relevant at this point.
this.prerelease.length = 0
this.inc('patch', identifier)
this.inc('pre', identifier)
this.inc('patch', identifier, identifierBase)
this.inc('pre', identifier, identifierBase)
break
// If the input is a non-prerelease version, this acts the same as
// prepatch.
case 'prerelease':
if (this.prerelease.length === 0) {
this.inc('patch', identifier)
this.inc('patch', identifier, identifierBase)
}
this.inc('pre', identifier)
this.inc('pre', identifier, identifierBase)
break

case 'major':
Expand Down Expand Up @@ -263,14 +263,15 @@ class SemVer {
}
}
if (identifier) {
const base = Number(identifierBase) ? 1 : 0
// 1.2.0-beta.1 bumps to 1.2.0-beta.2,
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
if (isNaN(this.prerelease[1])) {
this.prerelease = [identifier, 0]
this.prerelease = [identifier, base]
}
} else {
this.prerelease = [identifier, 0]
this.prerelease = [identifier, base]
}
}
break
Expand Down
5 changes: 3 additions & 2 deletions functions/inc.js
@@ -1,7 +1,8 @@
const SemVer = require('../classes/semver')

const inc = (version, release, options, identifier) => {
const inc = (version, release, options, identifier, identifierBase) => {
if (typeof (options) === 'string') {
identifierBase = identifier
identifier = options
options = undefined
}
Expand All @@ -10,7 +11,7 @@ const inc = (version, release, options, identifier) => {
return new SemVer(
version instanceof SemVer ? version.version : version,
options
).inc(release, identifier).version
).inc(release, identifier, identifierBase).version
} catch (er) {
return null
}
Expand Down
9 changes: 9 additions & 0 deletions tap-snapshots/test/bin/semver.js.test.cjs
Expand Up @@ -301,6 +301,15 @@ Object {
}
`

exports[`test/bin/semver.js TAP inc tests > -i premajor 1.0.0 --preid=beta -n 1 1`] = `
Object {
"code": 0,
"err": "",
"out": "2.0.0-beta.1\\n",
"signal": null,
}
`

exports[`test/bin/semver.js TAP inc tests > -i premajor 1.0.0 --preid=beta 1`] = `
Object {
"code": 0,
Expand Down
1 change: 1 addition & 0 deletions test/bin/semver.js
Expand Up @@ -29,6 +29,7 @@ t.test('inc tests', t => Promise.all([
['-i', 'major', '1.0.0'],
['-i', 'major', '1.0.0', '1.0.1'],
['-i', 'premajor', '1.0.0', '--preid=beta'],
['-i', 'premajor', '1.0.0', '--preid=beta', '-n', '1'],
['-i', '1.2.3'],
].map(args => t.resolveMatchSnapshot(run(args), args.join(' ')))))

Expand Down
5 changes: 3 additions & 2 deletions test/classes/semver.js
Expand Up @@ -84,12 +84,13 @@ test('incrementing', t => {
expect,
options,
id,
base,
]) => t.test(`${version} ${inc} ${id || ''}`.trim(), t => {
t.plan(1)
if (expect === null) {
t.throws(() => new SemVer(version, options).inc(inc, id))
t.throws(() => new SemVer(version, options).inc(inc, id, base))
} else {
t.equal(new SemVer(version, options).inc(inc, id).version, expect)
t.equal(new SemVer(version, options).inc(inc, id, base).version, expect)
}
}))
})
Expand Down
20 changes: 17 additions & 3 deletions test/fixtures/increments.js
@@ -1,5 +1,5 @@
// [version, inc, result, options, identifier]
// inc(version, inc) -> result
// [version, inc, result, options, identifier, identifierBase]
// inc(version, inc, options, identifier, identifierBase) -> result
module.exports = [
['1.2.3', 'major', '2.0.0'],
['1.2.3', 'minor', '1.3.0'],
Expand Down Expand Up @@ -82,9 +82,23 @@ module.exports = [
['1.2.0-1', 'minor', '1.2.0', false, 'dev'],
['1.0.0-1', 'major', '1.0.0', 'dev'],
['1.2.3-dev.bar', 'prerelease', '1.2.3-dev.0', false, 'dev'],

['1.2.3-0', 'prerelease', '1.2.3-1.0', false, '1'],
['1.2.3-1.0', 'prerelease', '1.2.3-1.1', false, '1'],
['1.2.3-1.1', 'prerelease', '1.2.3-1.2', false, '1'],
['1.2.3-1.1', 'prerelease', '1.2.3-2.0', false, '2'],

// [version, inc, result, identifierIndex, loose, identifier]
['1.2.0-1', 'prerelease', '1.2.0-alpha.0', false, 'alpha', '0'],
['1.2.1', 'prerelease', '1.2.2-alpha.0', false, 'alpha', '0'],
['0.2.0', 'prerelease', '0.2.1-alpha.0', false, 'alpha', '0'],
['1.2.2', 'prerelease', '1.2.3-alpha.1', false, 'alpha', '1'],
['1.2.3', 'prerelease', '1.2.4-alpha.1', false, 'alpha', '1'],
['1.2.4', 'prerelease', '1.2.5-alpha.1', false, 'alpha', '1'],
['1.2.0', 'prepatch', '1.2.1-dev.1', false, 'dev', '1'],
['1.2.0-1', 'prepatch', '1.2.1-dev.1', false, 'dev', '1'],
['1.2.0', 'premajor', '2.0.0-dev.0', false, 'dev', '0'],
['1.2.3-1', 'premajor', '2.0.0-dev.0', false, 'dev', '0'],
['1.2.3-dev.bar', 'prerelease', '1.2.3-dev.0', false, 'dev', '0'],
['1.2.0', 'preminor', '1.3.0-dev.1', false, 'dev', '1'],
['1.2.3-1', 'preminor', '1.3.0-dev.0', false, 'dev'],
]
12 changes: 6 additions & 6 deletions test/functions/inc.js
Expand Up @@ -4,20 +4,20 @@ const parse = require('../../functions/parse')
const increments = require('../fixtures/increments.js')

test('increment versions test', (t) => {
increments.forEach(([pre, what, wanted, options, id]) => {
const found = inc(pre, what, options, id)
const cmd = `inc(${pre}, ${what}, ${id})`
increments.forEach(([pre, what, wanted, options, id, base]) => {
const found = inc(pre, what, options, id, base)
const cmd = `inc(${pre}, ${what}, ${id}, ${base})`
t.equal(found, wanted, `${cmd} === ${wanted}`)

const parsed = parse(pre, options)
const parsedAsInput = parse(pre, options)
if (wanted) {
parsed.inc(what, id)
parsed.inc(what, id, base)
t.equal(parsed.version, wanted, `${cmd} object version updated`)
t.equal(parsed.raw, wanted, `${cmd} object raw field updated`)

const preIncObject = JSON.stringify(parsedAsInput)
inc(parsedAsInput, what, options, id)
inc(parsedAsInput, what, options, id, base)
const postIncObject = JSON.stringify(parsedAsInput)
t.equal(
postIncObject,
Expand All @@ -26,7 +26,7 @@ test('increment versions test', (t) => {
)
} else if (parsed) {
t.throws(() => {
parsed.inc(what, id)
parsed.inc(what, id, base)
})
} else {
t.equal(parsed, null)
Expand Down