diff --git a/README.md b/README.md index 0857c11..9710eb7 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Forked from [`version-bump-prompt`](https://github.com/JS-DevTools/version-bump- - Ships ESM and CJS bundles. - Add a new argument `--execute` to execute the command before committing. - Use current version's `preid` when avaliable. +- Confirmation before bumping. - Enable `--commit` `--tag` `--push` by default. (opt-out by `--no-push`, etc.)
diff --git a/src/cli/parse-args.ts b/src/cli/parse-args.ts index 316e2d6..4830e86 100644 --- a/src/cli/parse-args.ts +++ b/src/cli/parse-args.ts @@ -31,6 +31,7 @@ export function parseArgs(argv: string[]): ParsedArgs { .option('-c, --commit [msg]', 'Commit message', { default: true }) .option('-t, --tag [tag]', 'Tag name', { default: true }) .option('-p, --push', 'Push to remote', { default: true }) + .option('-y, --yes', 'Skip confirmation') .option('--no-verify', 'Skip git verification') .option('--ignore-scripts', 'Ignore scripts', { default: false }) .option('-q, --quiet', 'Quiet mode') @@ -50,6 +51,7 @@ export function parseArgs(argv: string[]): ParsedArgs { tag: args.tag, push: args.push, all: args.all, + confirm: !args.yes, noVerify: !args.verify, files: args['--'], ignoreScripts: args.ignoreScripts, diff --git a/src/get-new-version.ts b/src/get-new-version.ts index b401513..3112d76 100644 --- a/src/get-new-version.ts +++ b/src/get-new-version.ts @@ -85,20 +85,21 @@ async function promptForNewVersion(operation: Operation): Promise { const next = getNextVersions(oldVersion, release.preid) + const PADDING = 13 const answers = await prompts([ { type: 'autocomplete', name: 'release', - message: `Current version: ${green(oldVersion)}`, + message: `Current version ${green(oldVersion)}`, initial: 'next', choices: [ - { value: 'major', title: `major - ${bold(next.major)}` }, - { value: 'minor', title: `minor - ${bold(next.minor)}` }, - { value: 'patch', title: `patch - ${bold(next.patch)}` }, - { value: 'next', title: `next - ${bold(next.next)}` }, - { value: 'prerelease', title: `pre-release - ${bold(next.prerelease)}` }, - { value: 'none', title: `as-is - ${bold(oldVersion)}` }, - { value: 'custom', title: 'custom...' }, + { value: 'major', title: `${'major'.padStart(PADDING, ' ')} ${bold(next.major)}` }, + { value: 'minor', title: `${'minor'.padStart(PADDING, ' ')} ${bold(next.minor)}` }, + { value: 'patch', title: `${'patch'.padStart(PADDING, ' ')} ${bold(next.patch)}` }, + { value: 'next', title: `${'next'.padStart(PADDING, ' ')} ${bold(next.next)}` }, + { value: 'prerelease', title: `${'pre-release'.padStart(PADDING, ' ')} ${bold(next.prerelease)}` }, + { value: 'none', title: `${'as-is'.padStart(PADDING, ' ')} ${bold(oldVersion)}` }, + { value: 'custom', title: 'custom ...'.padStart(PADDING + 4, ' ') }, ], }, { diff --git a/src/git.ts b/src/git.ts index 95280b4..98a8874 100644 --- a/src/git.ts +++ b/src/git.ts @@ -87,7 +87,7 @@ export async function gitPush(operation: Operation): Promise { * If the template contains any "%s" placeholders, then they are replaced with the version number; * otherwise, the version number is appended to the string. */ -function formatVersionString(template: string, newVersion: string): string { +export function formatVersionString(template: string, newVersion: string): string { if (template.includes('%s')) return template.replace(/%s/g, newVersion) diff --git a/src/types/version-bump-options.ts b/src/types/version-bump-options.ts index 0c70952..9ac14cf 100644 --- a/src/types/version-bump-options.ts +++ b/src/types/version-bump-options.ts @@ -57,6 +57,13 @@ export interface VersionBumpOptions { */ all?: boolean + /** + * Prompt for confirmation + * + * @default false + */ + confirm?: boolean + /** * Indicates whether to bypass git commit hooks (`git commit --no-verify`). * diff --git a/src/version-bump.ts b/src/version-bump.ts index 8e2e140..0d6705d 100644 --- a/src/version-bump.ts +++ b/src/version-bump.ts @@ -1,8 +1,10 @@ import * as ezSpawn from '@jsdevtools/ez-spawn' +import { bold, cyan, green } from 'chalk' import { info, success } from 'log-symbols' +import prompts from 'prompts' import { getNewVersion } from './get-new-version' import { getOldVersion } from './get-old-version' -import { gitCommit, gitPush, gitTag } from './git' +import { formatVersionString, gitCommit, gitPush, gitTag } from './git' import { Operation } from './operation' import { runNpmScript } from './run-npm-script' import type { VersionBumpOptions } from './types/version-bump-options' @@ -39,7 +41,7 @@ export async function versionBump(options: VersionBumpOptions): Promise { +export async function versionBump(arg: VersionBumpOptions | string = {}): Promise { if (typeof arg === 'string') arg = { release: arg } @@ -49,6 +51,30 @@ export async function versionBump(arg: VersionBumpOptions | string = {}): Promis await getOldVersion(operation) await getNewVersion(operation) + if (arg.confirm) { + console.log() + console.log(` files ${operation.options.files.map(i => bold(i)).join(', ')}`) + if (operation.options.commit) + console.log(` commit ${bold(formatVersionString(operation.options.commit.message, operation.state.newVersion))}`) + if (operation.options.tag) + console.log(` tag ${bold(formatVersionString(operation.options.tag.name, operation.state.newVersion))}`) + if (operation.options.execute) + console.log(` execute ${bold(operation.options.execute)}`) + if (operation.options.push) + console.log(` push ${cyan(bold('yes'))}`) + console.log() + console.log(` from ${bold(operation.state.oldVersion)}`) + console.log(` to ${green(bold(operation.state.newVersion))}`) + console.log() + + if (!await prompts({ + name: 'yes', + type: 'confirm', + message: 'Bump', + }).then(r => r.yes)) + return + } + // Run npm preversion script, if any await runNpmScript(NpmScript.PreVersion, operation)