Skip to content

Commit 4877803

Browse files
muronggantfu
andauthoredMar 4, 2024
feat: allow passing --current-version to override the current version (#17)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
1 parent 81b7e35 commit 4877803

9 files changed

+50
-31
lines changed
 

‎src/cli/parse-args.ts

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export async function parseArgs(): Promise<ParsedArgs> {
4242
noVerify: !args.verify,
4343
files: [...(args['--'] || []), ...resultArgs],
4444
ignoreScripts: args.ignoreScripts,
45+
currentVersion: args.currentVersion,
4546
execute: args.execute,
4647
recursive: !!args.recursive,
4748
}),
@@ -113,6 +114,7 @@ export function loadCliArgs(argv = process.argv) {
113114
.option('--ignore-scripts', `Ignore scripts (default: ${bumpConfigDefaults.ignoreScripts})`)
114115
.option('-q, --quiet', 'Quiet mode')
115116
.option('-v, --version <version>', 'Target version')
117+
.option('--current-version <version>', 'Current version')
116118
.option('-x, --execute <command>', 'Commands to execute after version bumps')
117119
.help()
118120

‎src/get-old-version.ts ‎src/get-current-version.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import type { Operation } from './operation'
77
* Finds the current version number from files such as package.json.
88
* An error is thrown if no version number can be found.
99
*/
10-
export async function getOldVersion(operation: Operation): Promise<Operation> {
10+
export async function getCurrentVersion(operation: Operation): Promise<Operation> {
11+
if (operation.state.currentVersion)
12+
return operation
13+
1114
const { cwd, files } = operation.options
1215

1316
// Check all JSON files in the files list
@@ -24,8 +27,8 @@ export async function getOldVersion(operation: Operation): Promise<Operation> {
2427
if (version) {
2528
// We found the current version number!
2629
return operation.update({
27-
oldVersionSource: file,
28-
oldVersion: version,
30+
currentVersionSource: file,
31+
currentVersion: version,
2932
})
3033
}
3134
}

‎src/get-new-version.ts

+14-14
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { isPrerelease, releaseTypes } from './release-type'
1212
*/
1313
export async function getNewVersion(operation: Operation): Promise<Operation> {
1414
const { release } = operation.options
15-
const { oldVersion } = operation.state
15+
const { currentVersion } = operation.state
1616

1717
switch (release.type) {
1818
case 'prompt':
@@ -26,16 +26,16 @@ export async function getNewVersion(operation: Operation): Promise<Operation> {
2626
default:
2727
return operation.update({
2828
release: release.type,
29-
newVersion: getNextVersion(oldVersion, release),
29+
newVersion: getNextVersion(currentVersion, release),
3030
})
3131
}
3232
}
3333

3434
/**
3535
* Returns the next version number of the specified type.
3636
*/
37-
function getNextVersion(oldVersion: string, bump: BumpRelease): string {
38-
const oldSemVer = new SemVer(oldVersion)
37+
function getNextVersion(currentVersion: string, bump: BumpRelease): string {
38+
const oldSemVer = new SemVer(currentVersion)
3939

4040
const type = bump.type === 'next'
4141
? oldSemVer.prerelease.length ? 'prerelease' : 'patch'
@@ -63,15 +63,15 @@ function getNextVersion(oldVersion: string, bump: BumpRelease): string {
6363
/**
6464
* Returns the next version number for all release types.
6565
*/
66-
function getNextVersions(oldVersion: string, preid: string): Record<ReleaseType, string> {
66+
function getNextVersions(currentVersion: string, preid: string): Record<ReleaseType, string> {
6767
const next: Record<string, string> = {}
6868

69-
const parse = semver.parse(oldVersion)
69+
const parse = semver.parse(currentVersion)
7070
if (typeof parse?.prerelease[0] === 'string')
7171
preid = parse?.prerelease[0] || 'preid'
7272

7373
for (const type of releaseTypes)
74-
next[type] = getNextVersion(oldVersion, { type, preid })
74+
next[type] = getNextVersion(currentVersion, { type, preid })
7575

7676
return next
7777
}
@@ -82,18 +82,18 @@ function getNextVersions(oldVersion: string, preid: string): Record<ReleaseType,
8282
* @returns - A tuple containing the new version number and the release type (if any)
8383
*/
8484
async function promptForNewVersion(operation: Operation): Promise<Operation> {
85-
const { oldVersion } = operation.state
85+
const { currentVersion } = operation.state
8686
const release = operation.options.release as PromptRelease
8787

88-
const next = getNextVersions(oldVersion, release.preid)
89-
const configCustomVersion = await operation.options.customVersion?.(oldVersion, semver)
88+
const next = getNextVersions(currentVersion, release.preid)
89+
const configCustomVersion = await operation.options.customVersion?.(currentVersion, semver)
9090

9191
const PADDING = 13
9292
const answers = await prompts([
9393
{
9494
type: 'autocomplete',
9595
name: 'release',
96-
message: `Current version ${c.green(oldVersion)}`,
96+
message: `Current version ${c.green(currentVersion)}`,
9797
initial: configCustomVersion ? 'config' : 'next',
9898
choices: [
9999
{ value: 'major', title: `${'major'.padStart(PADDING, ' ')} ${c.bold(next.major)}` },
@@ -108,15 +108,15 @@ async function promptForNewVersion(operation: Operation): Promise<Operation> {
108108
{ value: 'prepatch', title: `${'pre-patch'.padStart(PADDING, ' ')} ${c.bold(next.prepatch)}` },
109109
{ value: 'preminor', title: `${'pre-minor'.padStart(PADDING, ' ')} ${c.bold(next.preminor)}` },
110110
{ value: 'premajor', title: `${'pre-major'.padStart(PADDING, ' ')} ${c.bold(next.premajor)}` },
111-
{ value: 'none', title: `${'as-is'.padStart(PADDING, ' ')} ${c.bold(oldVersion)}` },
111+
{ value: 'none', title: `${'as-is'.padStart(PADDING, ' ')} ${c.bold(currentVersion)}` },
112112
{ value: 'custom', title: 'custom ...'.padStart(PADDING + 4, ' ') },
113113
],
114114
},
115115
{
116116
type: prev => prev === 'custom' ? 'text' : null,
117117
name: 'custom',
118118
message: 'Enter the new version number:',
119-
initial: oldVersion,
119+
initial: currentVersion,
120120
validate: (custom: string) => {
121121
return isValidVersion(custom) ? true : 'That\'s not a valid version number'
122122
},
@@ -127,7 +127,7 @@ async function promptForNewVersion(operation: Operation): Promise<Operation> {
127127
}
128128

129129
const newVersion = answers.release === 'none'
130-
? oldVersion
130+
? currentVersion
131131
: answers.release === 'custom'
132132
? cleanVersion(answers.custom!)!
133133
: answers.release === 'config'

‎src/normalize-options.ts

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export interface NormalizedOptions {
5959
ignoreScripts: boolean
6060
execute?: string
6161
customVersion?: VersionBumpOptions['customVersion']
62+
currentVersion?: string
6263
}
6364

6465
/**
@@ -145,5 +146,6 @@ export async function normalizeOptions(raw: VersionBumpOptions): Promise<Normali
145146
ignoreScripts,
146147
execute,
147148
customVersion: raw.customVersion,
149+
currentVersion: raw.currentVersion,
148150
}
149151
}

‎src/operation.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ type ProgressCallback = (progress: VersionBumpProgress) => void
99

1010
interface OperationState {
1111
release: ReleaseType | undefined
12-
oldVersionSource: string
13-
oldVersion: string
12+
currentVersionSource: string
13+
currentVersion: string
1414
newVersion: string
1515
commitMessage: string
1616
tagName: string
@@ -37,8 +37,8 @@ export class Operation {
3737
*/
3838
public readonly state: Readonly<OperationState> = {
3939
release: undefined,
40-
oldVersion: '',
41-
oldVersionSource: '',
40+
currentVersion: '',
41+
currentVersionSource: '',
4242
newVersion: '',
4343
commitMessage: '',
4444
tagName: '',
@@ -55,7 +55,7 @@ export class Operation {
5555

5656
return {
5757
release: state.release,
58-
oldVersion: state.oldVersion,
58+
currentVersion: state.currentVersion,
5959
newVersion: state.newVersion,
6060
commit: options.commit ? state.commitMessage : false,
6161
tag: options.tag ? state.tagName : false,
@@ -75,6 +75,12 @@ export class Operation {
7575
private constructor(options: NormalizedOptions, progress?: ProgressCallback) {
7676
this.options = options
7777
this._progress = progress
78+
if (options.currentVersion) {
79+
this.update({
80+
currentVersion: options.currentVersion,
81+
currentVersionSource: 'user',
82+
})
83+
}
7884
}
7985

8086
/**

‎src/types/version-bump-options.ts

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ export interface VersionBumpOptions {
1616
*/
1717
release?: string
1818

19+
/**
20+
* The current version number to be bumpped.
21+
* If not provide, it will be read from the first file in the `files` array.
22+
*/
23+
currentVersion?: string
24+
1925
/**
2026
* The prerelease type (e.g. "alpha", "beta", "next").
2127
*

‎src/types/version-bump-results.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export interface VersionBumpResults {
1212
/**
1313
* The previous version number in package.json.
1414
*/
15-
oldVersion: string
15+
currentVersion: string
1616

1717
/**
1818
* The new version number.

‎src/update-files.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,15 @@ async function updateManifestFile(relPath: string, operation: Operation): Promis
8585
*/
8686
async function updateTextFile(relPath: string, operation: Operation): Promise<boolean> {
8787
const { cwd } = operation.options
88-
const { oldVersion, newVersion } = operation.state
88+
const { currentVersion, newVersion } = operation.state
8989
const modified = false
9090

9191
const file = await readTextFile(relPath, cwd)
9292

9393
// Only update the file if it contains at least one occurrence of the old version
94-
if (file.data.includes(oldVersion)) {
94+
if (file.data.includes(currentVersion)) {
9595
// Escape all non-alphanumeric characters in the version
96-
const sanitizedVersion = oldVersion.replace(/(\W)/g, '\\$1')
96+
const sanitizedVersion = currentVersion.replace(/(\W)/g, '\\$1')
9797

9898
// Replace occurrences of the old version number that are surrounded by word boundaries.
9999
// This ensures that it matches "1.23.456" or "v1.23.456", but not "321.23.456".

‎src/version-bump.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import c from 'picocolors'
44
import symbols from 'log-symbols'
55
import prompts from 'prompts'
66
import { getNewVersion } from './get-new-version'
7-
import { getOldVersion } from './get-old-version'
7+
import { getCurrentVersion } from './get-current-version'
88
import { formatVersionString, gitCommit, gitPush, gitTag } from './git'
99
import { Operation } from './operation'
1010
import { runNpmScript } from './run-npm-script'
@@ -42,14 +42,14 @@ export async function versionBump(options: VersionBumpOptions): Promise<VersionB
4242
* Bumps the version number in one or more files, prompting the user if necessary.
4343
* Optionally also commits, tags, and pushes to git.
4444
*/
45-
export async function versionBump(arg: VersionBumpOptions | string = {}): Promise<VersionBumpResults | undefined> {
45+
export async function versionBump(arg: (VersionBumpOptions) | string = {}): Promise<VersionBumpResults | undefined> {
4646
if (typeof arg === 'string')
4747
arg = { release: arg }
4848

4949
const operation = await Operation.start(arg)
5050

5151
// Get the old and new version numbers
52-
await getOldVersion(operation)
52+
await getCurrentVersion(operation)
5353
await getNewVersion(operation)
5454

5555
if (arg.confirm) {
@@ -104,7 +104,7 @@ function printSummary(operation: Operation) {
104104
if (operation.options.push)
105105
console.log(` push ${c.cyan(c.bold('yes'))}`)
106106
console.log()
107-
console.log(` from ${c.bold(operation.state.oldVersion)}`)
107+
console.log(` from ${c.bold(operation.state.currentVersion)}`)
108108
console.log(` to ${c.green(c.bold(operation.state.newVersion))}`)
109109
console.log()
110110
}
@@ -119,7 +119,7 @@ export async function versionBumpInfo(arg: VersionBumpOptions | string = {}): Pr
119119
const operation = await Operation.start(arg)
120120

121121
// Get the old and new version numbers
122-
await getOldVersion(operation)
122+
await getCurrentVersion(operation)
123123
await getNewVersion(operation)
124124
return operation
125125
}

0 commit comments

Comments
 (0)
Please sign in to comment.