Skip to content

Commit e6c63e2

Browse files
committed
replace minimist with util.parseArgs
1 parent 94a4f68 commit e6c63e2

3 files changed

Lines changed: 44 additions & 120 deletions

File tree

index.ts

Lines changed: 32 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
#!/usr/bin/env node
22
import nanoSpawn from "nano-spawn";
3-
import minimist from "minimist";
3+
import {parseArgs} from "node:util";
44
import {basename, dirname, join, relative} from "node:path";
5-
import {cwd, exit as doExit, stdout, argv} from "node:process";
5+
import {cwd, exit as doExit, stdout} from "node:process";
66
import {EOL, platform} from "node:os";
77
import {readFileSync, writeFileSync, accessSync, truncateSync, statSync} from "node:fs";
88
import pkg from "./package.json" with {type: "json"};
99
import {parse} from "smol-toml";
10-
import type {Opts as MinimistOpts} from "minimist";
1110
import type {Result} from "nano-spawn";
1211

1312
export type SemverLevel = "patch" | "minor" | "major";
@@ -24,39 +23,6 @@ function uniq<T extends Array<any>>(arr: T): T {
2423
return Array.from(new Set(arr)) as T;
2524
}
2625

27-
const minOpts: MinimistOpts = {
28-
boolean: [
29-
"a", "all",
30-
"D", "dry",
31-
"g", "gitless",
32-
"h", "help",
33-
"P", "packageless",
34-
"p", "prefix",
35-
"v", "version",
36-
],
37-
string: [
38-
"b", "base",
39-
"c", "command",
40-
"d", "date",
41-
"r", "replace",
42-
"m", "message",
43-
"_",
44-
],
45-
alias: {
46-
a: "all",
47-
b: "base",
48-
c: "command",
49-
d: "date",
50-
D: "dry",
51-
g: "gitless",
52-
h: "help",
53-
m: "message",
54-
p: "prefix",
55-
r: "replace",
56-
v: "version",
57-
}
58-
};
59-
6026
function replaceTokens(str: string, newVersion: string): string {
6127
const [major, minor, patch] = newVersion.split(".");
6228
return str
@@ -177,44 +143,6 @@ function write(file: string, content: string): void {
177143
}
178144
}
179145

180-
function parseMixedArg(arg: any) {
181-
if (arg === "") {
182-
return true;
183-
} else if (typeof arg === "string") {
184-
return arg.includes(",") ? arg.split(",") : [arg];
185-
} else if (Array.isArray(arg)) {
186-
return arg;
187-
} else {
188-
return Boolean(arg);
189-
}
190-
}
191-
192-
// handle minimist parsing issues like '-d patch'
193-
function fixArgs(commands: Set<string>, args: any, minOpts: MinimistOpts) {
194-
for (const key of Object.keys(minOpts.alias as object)) {
195-
delete args[key];
196-
}
197-
198-
if (commands.has(args.date)) {
199-
args._ = [args.date, ...args._];
200-
args.date = true;
201-
}
202-
if (commands.has(args.base)) {
203-
args._ = [args.base, ...args._];
204-
args.base = true;
205-
}
206-
if (commands.has(args.command)) {
207-
args._ = [args.command, ...args._];
208-
args.command = "";
209-
}
210-
if (commands.has(args.replace)) {
211-
args._ = [args.replace, ...args._];
212-
args.replace = "";
213-
}
214-
215-
return args;
216-
}
217-
218146
// join strings, ignoring falsy values and trimming the result
219147
function joinStrings(strings: Array<string | undefined>, separator: string): string {
220148
const arr: Array<string> = [];
@@ -245,8 +173,26 @@ function writeResult(result: Result): void {
245173

246174
async function main(): Promise<void> {
247175
const commands = new Set(["patch", "minor", "major"]);
248-
const args = fixArgs(commands, minimist(argv.slice(2), minOpts), minOpts);
249-
let [level, ...files]: [SemverLevel, ...Array<string>] = args._;
176+
const result = parseArgs({
177+
strict: true,
178+
allowPositionals: true,
179+
options: {
180+
all: {short: "a", type: "boolean"},
181+
dry: {short: "D", type: "boolean"},
182+
gitless: {short: "g", type: "boolean"},
183+
help: {short: "h", type: "boolean"},
184+
packageless: {short: "P", type: "boolean"},
185+
prefix: {short: "p", type: "boolean"},
186+
version: {short: "v", type: "boolean"},
187+
date: {short: "d", type: "boolean"},
188+
base: {short: "b", type: "string"},
189+
command: {short: "c", type: "string"},
190+
replace: {short: "r", type: "string", multiple: true},
191+
message: {short: "m", type: "string"},
192+
},
193+
});
194+
const args = result.values;
195+
let [level, ...files] = result.positionals;
250196
files = uniq(files);
251197

252198
if (args.version) {
@@ -262,7 +208,7 @@ async function main(): Promise<void> {
262208
-b, --base <version> Base version. Default is from latest git tag or 0.0.0
263209
-p, --prefix Prefix version string with a "v" character. Default is none
264210
-c, --command <cmd> Run command after files are updated but before git commit and tag
265-
-d, --date [<date>] Replace dates in format YYYY-MM-DD with current or given date
211+
-d, --date Replace dates in format YYYY-MM-DD with current date
266212
-m, --message <str> Custom tag and commit message
267213
-r, --replace <str> Additional replacements in the format "s#regexp#replacement#flags"
268214
-g, --gitless Do not perform any git action like creating commit and tag
@@ -278,17 +224,9 @@ async function main(): Promise<void> {
278224
exit();
279225
}
280226

281-
let date: any = parseMixedArg(args.date);
282-
if (date) {
283-
if (date === true) {
284-
date = (new Date()).toISOString().substring(0, 10);
285-
} else if (Array.isArray(date)) {
286-
date = date[date.length - 1];
287-
}
288-
289-
if (typeof date !== "string" || !/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/.test(date)) {
290-
exit(`Invalid date argument: ${date}`);
291-
}
227+
let date = "";
228+
if (args.date) {
229+
date = (new Date()).toISOString().substring(0, 10);
292230
}
293231

294232
const pwd = cwd();
@@ -314,7 +252,7 @@ async function main(): Promise<void> {
314252
baseVersion = "0.0.0";
315253
}
316254
} else {
317-
baseVersion = args.base;
255+
baseVersion = String(args.base);
318256
}
319257

320258
// chop off "v"
@@ -329,11 +267,11 @@ async function main(): Promise<void> {
329267
files = files.map(file => relative(pwd, file));
330268

331269
// set new version
332-
const newVersion = incrementSemver(baseVersion, level);
270+
const newVersion = incrementSemver(baseVersion, level as SemverLevel);
333271

334272
const replacements: Array<{re: RegExp, replacement: string}> = [];
335273
if (args.replace) {
336-
args.replace = Array.isArray(args.replace) ? args.replace : [args.replace];
274+
args.replace = (Array.isArray(args.replace) ? args.replace : [args.replace] as Array<string>);
337275
for (const replaceStr of args.replace) {
338276
let [_, re, replacement, flags] = (/^s#(.+?)#(.+?)#(.*)$/.exec(replaceStr) || []);
339277

@@ -371,13 +309,8 @@ async function main(): Promise<void> {
371309
}
372310
if (args.gitless) return; // nothing else to do
373311

374-
const messages: Array<string> = parseMixedArg(args.message) as Array<string>;
312+
const msg = args.message;
375313
const tagName = args["prefix"] ? `v${newVersion}` : newVersion;
376-
const msgs: Array<string> = [];
377-
378-
if (messages) {
379-
msgs.push(...messages.map(message => replaceTokens(message, newVersion)));
380-
}
381314

382315
// check if base tag exists
383316
let range = "";
@@ -411,7 +344,7 @@ async function main(): Promise<void> {
411344
}
412345

413346
// create commit
414-
const commitMsg = joinStrings([tagName, ...msgs, changelog], "\n\n");
347+
const commitMsg = joinStrings([tagName, msg, changelog].filter(Boolean), "\n\n");
415348
if (args.all) {
416349
writeResult(await nanoSpawn("git", ["commit", "-a", "--allow-empty", "-F", "-"], {stdin: {string: commitMsg}}));
417350
} else {
@@ -425,7 +358,7 @@ async function main(): Promise<void> {
425358
}
426359

427360
// create tag
428-
const tagMsg = joinStrings([...msgs, changelog], "\n\n");
361+
const tagMsg = joinStrings([msg, changelog].filter(Boolean), "\n\n");
429362
// adding explicit -a here seems to make git no longer sign the tag
430363
writeResult(await nanoSpawn("git", ["tag", "-f", "-F", "-", tagName], {stdin: {string: tagMsg}}));
431364
}

package-lock.json

Lines changed: 12 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@
1515
"node": ">=20"
1616
},
1717
"devDependencies": {
18-
"@types/minimist": "1.2.5",
1918
"@types/node": "24.7.0",
2019
"eslint": "9.37.0",
2120
"eslint-config-silverwind": "105.2.3",
22-
"minimist": "1.2.8",
2321
"nano-spawn": "1.0.3",
2422
"smol-toml": "1.4.2",
2523
"tsdown": "0.15.6",

0 commit comments

Comments
 (0)