forked from JS-DevTools/version-bump-prompt
-
-
Notifications
You must be signed in to change notification settings - Fork 35
/
parse-args.ts
122 lines (111 loc) · 4.44 KB
/
parse-args.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import process from 'node:process'
import fs from 'node:fs/promises'
import fsSync from 'node:fs'
import { valid as isValidVersion } from 'semver'
import cac from 'cac'
import c from 'picocolors'
import yaml from 'js-yaml'
import { isReleaseType } from '../release-type'
import type { VersionBumpOptions } from '../types/version-bump-options'
import { version } from '../../package.json'
import { bumpConfigDefaults, loadBumpConfig } from '../config'
import { ExitCode } from './exit-code'
/**
* The parsed command-line arguments
*/
export interface ParsedArgs {
help?: boolean
version?: boolean
quiet?: boolean
options: VersionBumpOptions
}
/**
* Parses the command-line arguments
*/
export async function parseArgs(): Promise<ParsedArgs> {
try {
const cli = cac('bumpp')
cli
.version(version)
.usage('[...files]')
.option('--preid <preid>', 'ID for prerelease')
.option('--all', `Include all files (default: ${bumpConfigDefaults.all})`)
.option('-c, --commit [msg]', `Commit message (default: ${bumpConfigDefaults.commit})`)
.option('--no-commit', 'Skip commit')
.option('-t, --tag [tag]', `Tag name (default: ${bumpConfigDefaults.tag})`)
.option('--no-tag', 'Skip tag')
.option('-p, --push', `Push to remote (default: ${bumpConfigDefaults.push})`)
.option('-y, --yes', `Skip confirmation (default: ${!bumpConfigDefaults.confirm})`)
.option('-r, --recursive', `Bump package.json files recursively (default: ${bumpConfigDefaults.recursive})`)
.option('--no-verify', 'Skip git verification')
.option('--ignore-scripts', `Ignore scripts (default: ${bumpConfigDefaults.ignoreScripts})`)
.option('-q, --quiet', 'Quiet mode')
.option('-v, --version <version>', 'Target version')
.option('-x, --execute <command>', 'Commands to execute after version bumps')
.help()
const result = cli.parse()
const args = result.options
const parsedArgs: ParsedArgs = {
help: args.help as boolean,
version: args.version as boolean,
quiet: args.quiet as boolean,
options: await loadBumpConfig({
preid: args.preid,
commit: !args.noCommit && args.commit,
tag: !args.noTag && args.tag,
push: args.push,
all: args.all,
confirm: !args.yes,
noVerify: !args.verify,
files: [...(args['--'] || []), ...result.args],
ignoreScripts: args.ignoreScripts,
execute: args.execute,
recursive: !!args.recursive,
}),
}
// If a version number or release type was specified, then it will mistakenly be added to the "files" array
if (parsedArgs.options.files && parsedArgs.options.files.length > 0) {
const firstArg = parsedArgs.options.files[0]
if (firstArg === 'prompt' || isReleaseType(firstArg) || isValidVersion(firstArg)) {
parsedArgs.options.release = firstArg
parsedArgs.options.files.shift()
}
}
if (parsedArgs.options.recursive) {
if (parsedArgs.options.files?.length) {
console.log(c.yellow('The --recursive option is ignored when files are specified'))
}
else {
parsedArgs.options.files = [
'package.json',
'package-lock.json',
'packages/**/package.json',
'jsr.json',
'jsr.jsonc',
]
// check if pnpm-workspace.yaml exists, if so, add all workspaces to files
if (fsSync.existsSync('pnpm-workspace.yaml')) {
// read pnpm-workspace.yaml
const pnpmWorkspace = await fs.readFile('pnpm-workspace.yaml', 'utf8')
// parse yaml
const workspaces = yaml.load(pnpmWorkspace) as { packages: string[] }
// append package.json to each workspace string
const workspacesWithPackageJson = workspaces.packages.map(workspace => `${workspace}/package.json`)
// start with ! or already in files should be excluded
const withoutExcludedWorkspaces = workspacesWithPackageJson.filter(workspace => !workspace.startsWith('!') && !parsedArgs.options.files?.includes(workspace))
// add to files
parsedArgs.options.files = parsedArgs.options.files.concat(withoutExcludedWorkspaces)
}
}
}
return parsedArgs
}
catch (error) {
// There was an error parsing the command-line args
return errorHandler(error as Error)
}
}
function errorHandler(error: Error): never {
console.error(error.message)
return process.exit(ExitCode.InvalidArgument)
}