UNPKG

@eighty4/changelog

Version:
169 lines (154 loc) 4.81 kB
#!/usr/bin/env node import { BadChangelogError, type ChangelogErrorKind, CliError, } from './errors.ts' import { checkUnreleasedFromCliArgs } from './task.check.ts' import { getVersionContentFromCliArgs } from './task.get.ts' import { makeNewChangelogFromCliArgs } from './task.new.ts' import { nextVersionRolloverFromCliArgs } from './task.rollover.ts' if (process.argv.find(a => a === '--debug-args')) { console.log(JSON.stringify(process.argv, null, 4)) process.exit(0) } let args = [...process.argv] let shiftingEntrypoint: string | undefined while ((shiftingEntrypoint = args.shift())) { if ( typeof shiftingEntrypoint === 'undefined' || ['changelog', 'bin.ts', 'bin.js'].find(p => shiftingEntrypoint?.endsWith(p), ) ) { break } } let task: 'check' | 'get' | 'new' | 'rollover' | undefined = undefined if (args.some(arg => arg === '-h' || arg === '--help')) { printHelp() } let shifted: string | undefined switch ((shifted = args.shift())) { case 'init': case 'new': task = 'new' break case 'check': task = 'check' break case 'get': task = 'get' break case 'rollover': task = 'rollover' break default: if (typeof shifted === 'undefined') { printHelp('missing command') } else { printHelp(shifted + " isn't a command") } } try { switch (task) { case 'check': process.exit((await checkUnreleasedFromCliArgs(args)) ? 0 : 1) case 'get': console.log(await getVersionContentFromCliArgs(args)) process.exit(0) case 'new': console.log(makeNewChangelogFromCliArgs(args)) process.exit(0) case 'rollover': await nextVersionRolloverFromCliArgs(args) process.exit(0) } } catch (e: unknown) { errorExit(e) } function printHelp(error?: string): never { if (error) printError(error) const bold = (s: string) => `\u001b[1m${s}\u001b[0m` if (!task || task === 'check') { console.log(`changelog check [--changelog-file CHANGELOG_FILE]`) } if (!task || task === 'get') { console.log( `changelog get ${bold('VERSION')} [--changelog-file CHANGELOG_FILE]`, ) } if (!task || task === 'new') { console.log(`changelog new ${bold('--repo OWNER/NAME')}`) } if (!task || task === 'rollover') { console.log( `changelog rollover ${bold('NEXT_VERSION')} [--git-tag GIT_TAG] [--changelog-file CHANGELOG_FILE]`, ) } process.exit(1) } function printError(e: unknown) { if (e !== null) { if (typeof e === 'string') { console.error(red('error:'), e) } else if (e instanceof Error) { console.error(red('error:'), e.message) if (e instanceof BadChangelogError) { for (const error of e.errors) { const { excerpt, kind, line } = error console.error( ` at line ${line}, ${changelogErrorDescription(kind)}`, ) console.error( ` ${changelogErrorCorrection(kind, excerpt)}`, ) } } else if (e instanceof CliError) { console.log('changelog -h for more details') } } } } function changelogErrorDescription(kind: ChangelogErrorKind): string { switch (kind) { case 'release-header': return 'release header is not valid' case 'version-brackets': return 'release version must be in Markdown link brackets' case 'version-semver': return 'release version is not a valid semver' } } function changelogErrorCorrection( kind: ChangelogErrorKind, excerpt: string, ): string | undefined { switch (kind) { case 'version-brackets': return `${excerpt} -> ${excerpt .split(/\s+/) .map((s, i) => (i === 1 ? `${green('[')}${s}${green(']')}` : s)) .join(' ')}` case 'version-semver': return `${excerpt .split(/\s+/) .map((s, i) => (i === 1 ? red(s) : s)) .join(' ')} -> ${excerpt .split(/\s+/) .map((s, i) => (i === 1 ? green('[vX.X.X]') : s)) .join(' ')}` default: return excerpt } } function green(s: string): string { return `\u001b[32m${s}\u001b[0m` } function red(s: string): string { return `\u001b[31m${s}\u001b[0m` } function errorExit(e?: unknown): never { printError(e) process.exit(1) }