@vlandoss/run-run 0.5.2 → 0.5.3-git-87ebfca.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.usage.kdl +1 -1
- package/dist/run.mjs +64 -61
- package/package.json +3 -3
- package/src/program/commands/test-static.ts +1 -1
- package/src/program/commands/tscheck.ts +5 -4
- package/src/program/commands/x.ts +1 -2
- package/src/services/biome.ts +13 -23
- package/src/services/ctx.ts +1 -4
- package/src/services/oxfmt.ts +3 -9
- package/src/services/oxlint.ts +3 -9
- package/src/services/tool.ts +11 -43
- package/src/services/tsc.ts +5 -1
- package/src/services/tsdown.ts +5 -1
- package/src/types/tool.ts +1 -1
package/dist/cli.usage.kdl
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @generated by @usage-spec/commander from Commander.js metadata
|
|
2
2
|
name rr
|
|
3
3
|
bin rr
|
|
4
|
-
version "0.5.
|
|
4
|
+
version "0.5.3-git-87ebfca.0"
|
|
5
5
|
usage "[options] <command...>"
|
|
6
6
|
flag --usage help="print KDL spec for this CLI (https://kdl.dev)"
|
|
7
7
|
cmd completion help="print shell completion script 🐚 (usage)" {
|
package/dist/run.mjs
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
1
|
import path from "node:path";
|
|
3
|
-
import { colorize, createPkg, createShellService, cwd, dirnameOf, isCI, palette, run, text } from "@vlandoss/clibuddy";
|
|
2
|
+
import { colorize, createPkg, createShellService, cwd, dirnameOf, isCI, palette, resolveBinPath, run, text } from "@vlandoss/clibuddy";
|
|
4
3
|
import { Argument, Option, createCommand } from "commander";
|
|
5
4
|
import fs from "node:fs";
|
|
6
5
|
import os from "node:os";
|
|
7
6
|
import { lilconfig } from "lilconfig";
|
|
8
7
|
import { createLoggy } from "@vlandoss/loggy";
|
|
9
|
-
import memoize from "memoize";
|
|
10
8
|
import { glob } from "glob";
|
|
11
9
|
import { rimraf } from "rimraf";
|
|
10
|
+
import memoize from "memoize";
|
|
12
11
|
import { generateToStdout } from "@usage-spec/commander";
|
|
13
|
-
//#region \0rolldown/runtime.js
|
|
14
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
15
|
-
//#endregion
|
|
16
12
|
//#region src/services/logger.ts
|
|
17
13
|
const logger = createLoggy({ namespace: "run-run" });
|
|
18
14
|
//#endregion
|
|
@@ -68,10 +64,7 @@ async function createContext(binDir) {
|
|
|
68
64
|
if (!appPkg) throw new Error("Could not find app package.json");
|
|
69
65
|
debug("app pkg info: %O", appPkg.info());
|
|
70
66
|
debug("bin pkg info: %O", binPkg.info());
|
|
71
|
-
const shell = createShellService(
|
|
72
|
-
localBaseBinPath: [binDir],
|
|
73
|
-
stdio: "inherit"
|
|
74
|
-
});
|
|
67
|
+
const shell = createShellService();
|
|
75
68
|
debug("shell service options: %O", shell.options);
|
|
76
69
|
return {
|
|
77
70
|
appPkg,
|
|
@@ -130,38 +123,20 @@ var ToolService = class {
|
|
|
130
123
|
this.#ui = ui ?? bin;
|
|
131
124
|
this.#shellService = shellService;
|
|
132
125
|
}
|
|
133
|
-
async exec(args) {
|
|
134
|
-
|
|
135
|
-
return this.#run(shell, args);
|
|
126
|
+
async exec(args = []) {
|
|
127
|
+
return this.#shellService.run(this.getBinDir(), args, { display: this.#bin });
|
|
136
128
|
}
|
|
137
129
|
async doctor() {
|
|
138
|
-
const
|
|
139
|
-
const output = await this.#run(shell, "--help");
|
|
130
|
+
const output = await this.#shellService.runCaptured(this.getBinDir(), ["--help"], { throwOnError: false });
|
|
140
131
|
return {
|
|
141
132
|
ok: output.exitCode === 0,
|
|
142
|
-
output
|
|
133
|
+
output: {
|
|
134
|
+
stdout: output.stdout,
|
|
135
|
+
stderr: output.stderr,
|
|
136
|
+
exitCode: output.exitCode
|
|
137
|
+
}
|
|
143
138
|
};
|
|
144
139
|
}
|
|
145
|
-
#shell = memoize((cwd) => {
|
|
146
|
-
const preferLocal = this.#getPreferLocal();
|
|
147
|
-
return this.#shellService.child({
|
|
148
|
-
...cwd && { cwd },
|
|
149
|
-
...preferLocal && { preferLocal }
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
#run(shell, args) {
|
|
153
|
-
if (!args) return shell.$`${this.#bin}`;
|
|
154
|
-
return shell.$`${this.#bin} ${typeof args === "string" ? args : args.join(" ")}`;
|
|
155
|
-
}
|
|
156
|
-
#getPreferLocal() {
|
|
157
|
-
if (!this.getBinDir) return;
|
|
158
|
-
try {
|
|
159
|
-
const binPath = this.getBinDir();
|
|
160
|
-
return fs.statSync(binPath).isDirectory() ? binPath : path.dirname(binPath);
|
|
161
|
-
} catch {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
140
|
get bin() {
|
|
166
141
|
return this.#bin;
|
|
167
142
|
}
|
|
@@ -179,6 +154,9 @@ var TsdownService = class extends ToolService {
|
|
|
179
154
|
shellService
|
|
180
155
|
});
|
|
181
156
|
}
|
|
157
|
+
getBinDir() {
|
|
158
|
+
return resolveBinPath("tsdown", { from: import.meta.url });
|
|
159
|
+
}
|
|
182
160
|
async buildLib() {
|
|
183
161
|
await this.exec();
|
|
184
162
|
}
|
|
@@ -263,6 +241,7 @@ function createConfigCommand(ctx) {
|
|
|
263
241
|
}
|
|
264
242
|
//#endregion
|
|
265
243
|
//#region src/services/biome.ts
|
|
244
|
+
const COMMON_FLAGS = ["--colors=force", "--no-errors-on-unmatched"];
|
|
266
245
|
var BiomeService = class extends ToolService {
|
|
267
246
|
constructor(shellService) {
|
|
268
247
|
super({
|
|
@@ -272,23 +251,38 @@ var BiomeService = class extends ToolService {
|
|
|
272
251
|
});
|
|
273
252
|
}
|
|
274
253
|
getBinDir() {
|
|
275
|
-
return
|
|
254
|
+
return resolveBinPath("@biomejs/biome", {
|
|
255
|
+
from: import.meta.url,
|
|
256
|
+
binName: "biome"
|
|
257
|
+
});
|
|
276
258
|
}
|
|
277
259
|
async format(options) {
|
|
278
|
-
const
|
|
279
|
-
if (options.fix)
|
|
280
|
-
|
|
260
|
+
const args = ["format", ...COMMON_FLAGS];
|
|
261
|
+
if (options.fix) args.push("--fix");
|
|
262
|
+
await this.exec(args);
|
|
281
263
|
}
|
|
282
264
|
async lint(options) {
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
265
|
+
const args = [
|
|
266
|
+
"check",
|
|
267
|
+
...COMMON_FLAGS,
|
|
268
|
+
"--formatter-enabled=false"
|
|
269
|
+
];
|
|
270
|
+
if (options.fix) args.push("--fix", "--unsafe");
|
|
271
|
+
await this.exec(args);
|
|
286
272
|
}
|
|
287
273
|
async check(options) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
274
|
+
if (options.fix) await this.exec([
|
|
275
|
+
"check",
|
|
276
|
+
...COMMON_FLAGS,
|
|
277
|
+
"--fix"
|
|
278
|
+
]);
|
|
279
|
+
else if (options.fixStaged) await this.exec([
|
|
280
|
+
"check",
|
|
281
|
+
...COMMON_FLAGS,
|
|
282
|
+
"--fix",
|
|
283
|
+
"--staged"
|
|
284
|
+
]);
|
|
285
|
+
else await this.exec([isCI ? "ci" : "check", ...COMMON_FLAGS]);
|
|
292
286
|
}
|
|
293
287
|
};
|
|
294
288
|
//#endregion
|
|
@@ -302,12 +296,10 @@ var OxfmtService = class extends ToolService {
|
|
|
302
296
|
});
|
|
303
297
|
}
|
|
304
298
|
getBinDir() {
|
|
305
|
-
return
|
|
299
|
+
return resolveBinPath("oxfmt", { from: import.meta.url });
|
|
306
300
|
}
|
|
307
301
|
async format(options) {
|
|
308
|
-
|
|
309
|
-
if (options.fix) await this.exec(`${commonOptions} --fix`);
|
|
310
|
-
else await this.exec(`${commonOptions} --check`);
|
|
302
|
+
await this.exec(["--no-error-on-unmatched-pattern", options.fix ? "--fix" : "--check"]);
|
|
311
303
|
}
|
|
312
304
|
};
|
|
313
305
|
//#endregion
|
|
@@ -342,12 +334,10 @@ var OxlintService = class extends ToolService {
|
|
|
342
334
|
});
|
|
343
335
|
}
|
|
344
336
|
getBinDir() {
|
|
345
|
-
return
|
|
337
|
+
return resolveBinPath("oxlint", { from: import.meta.url });
|
|
346
338
|
}
|
|
347
339
|
async lint(options) {
|
|
348
|
-
|
|
349
|
-
if (options.fix) await this.exec(`${commonOptions} --fix`);
|
|
350
|
-
else await this.exec(`${commonOptions} --check`);
|
|
340
|
+
await this.exec(["--report-unused-disable-directives", options.fix ? "--fix" : "--check"]);
|
|
351
341
|
}
|
|
352
342
|
};
|
|
353
343
|
//#endregion
|
|
@@ -402,7 +392,11 @@ function createPkgsCommand(ctx) {
|
|
|
402
392
|
//#region src/program/commands/test-static.ts
|
|
403
393
|
function createTestStaticCommand(ctx) {
|
|
404
394
|
return createCommand("test:static").summary(`run static tests 🔬 (${TOOL_LABELS.RUN_RUN})`).description("Runs static tests, including linting, formatting checks, and TypeScript type checking, to ensure code quality and correctness without executing the code.").action(async function testStaticAction() {
|
|
405
|
-
await ctx.shell
|
|
395
|
+
await ctx.shell.run("rr", [
|
|
396
|
+
"x",
|
|
397
|
+
"jscheck",
|
|
398
|
+
"tscheck"
|
|
399
|
+
]);
|
|
406
400
|
});
|
|
407
401
|
}
|
|
408
402
|
//#endregion
|
|
@@ -435,6 +429,12 @@ var TscService = class extends ToolService {
|
|
|
435
429
|
shellService
|
|
436
430
|
});
|
|
437
431
|
}
|
|
432
|
+
getBinDir() {
|
|
433
|
+
return resolveBinPath("typescript", {
|
|
434
|
+
from: import.meta.url,
|
|
435
|
+
binName: "tsc"
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
438
|
};
|
|
439
439
|
//#endregion
|
|
440
440
|
//#region src/program/commands/tscheck.ts
|
|
@@ -451,7 +451,7 @@ async function typecheckAt({ dir, scripts, log, shell, run }) {
|
|
|
451
451
|
const preScript = getPreScript(scripts);
|
|
452
452
|
if (preScript) {
|
|
453
453
|
log.start(`Running pre-script: ${preScript}`);
|
|
454
|
-
await shellAt
|
|
454
|
+
await shellAt.run(preScript, [], { shell: true });
|
|
455
455
|
log.success("Pre-script completed");
|
|
456
456
|
}
|
|
457
457
|
log.start("Type checking started");
|
|
@@ -469,8 +469,12 @@ function createTsCheckCommand(ctx) {
|
|
|
469
469
|
return createCommand("tsc").alias("tscheck").summary(`check typescript errors 📐 (${toolUi})`).description("Checks the TypeScript code for type errors, ensuring that the code adheres to the defined type constraints and helps catch potential issues before runtime.").addCommand(createDoctorSubcommand(doctorService)).addHelpText("afterAll", `\nUnder the hood, this command uses the ${toolUi} CLI to check the code.`).action(async function typecheckAction() {
|
|
470
470
|
const isTsProject = (dir) => appPkg.hasFile("tsconfig.json", dir);
|
|
471
471
|
const runTypecheck = async (shell) => {
|
|
472
|
-
if (config.future?.oxc) await new OxlintService(shell).exec(
|
|
473
|
-
|
|
472
|
+
if (config.future?.oxc) await new OxlintService(shell).exec([
|
|
473
|
+
"--type-aware",
|
|
474
|
+
"--type-check",
|
|
475
|
+
"--report-unused-disable-directives"
|
|
476
|
+
]);
|
|
477
|
+
else await new TscService(shell).exec(["--noEmit"]);
|
|
474
478
|
};
|
|
475
479
|
if (!appPkg.isMonorepo()) {
|
|
476
480
|
if (!isTsProject(appPkg.dirPath)) {
|
|
@@ -515,8 +519,7 @@ function addUsage(program) {
|
|
|
515
519
|
//#region src/program/commands/x.ts
|
|
516
520
|
function createXCommand(ctx) {
|
|
517
521
|
return createCommand("x").summary("run multiple rr subcommands concurrently").description("Run multiple rr subcommands concurrently (e.g. `rr x jsc tsc`).").argument("<cmds...>", "rr subcommands to execute concurrently").action(async function runXAction(cmds) {
|
|
518
|
-
|
|
519
|
-
if ((await Promise.allSettled(cmds.map((cmd) => $`rr ${cmd}`))).some((r) => r.status === "rejected")) process.exitCode = 1;
|
|
522
|
+
if ((await Promise.allSettled(cmds.map((cmd) => ctx.shell.run("rr", [cmd])))).some((r) => r.status === "rejected")) process.exitCode = 1;
|
|
520
523
|
});
|
|
521
524
|
}
|
|
522
525
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vlandoss/run-run",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3-git-87ebfca.0",
|
|
4
4
|
"description": "The CLI toolbox to fullstack common scripts in Variable Land",
|
|
5
5
|
"homepage": "https://github.com/variableland/dx/tree/main/packages/run-run#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"rimraf": "6.1.3",
|
|
64
64
|
"tsdown": "0.21.10",
|
|
65
65
|
"typescript": "6.0.3",
|
|
66
|
-
"@vlandoss/
|
|
67
|
-
"@vlandoss/
|
|
66
|
+
"@vlandoss/clibuddy": "0.5.1-git-87ebfca.0",
|
|
67
|
+
"@vlandoss/loggy": "0.2.0"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@vlandoss/tsdown-config": "^0.0.1"
|
|
@@ -9,6 +9,6 @@ export function createTestStaticCommand(ctx: Context) {
|
|
|
9
9
|
"Runs static tests, including linting, formatting checks, and TypeScript type checking, to ensure code quality and correctness without executing the code.",
|
|
10
10
|
)
|
|
11
11
|
.action(async function testStaticAction() {
|
|
12
|
-
await ctx.shell
|
|
12
|
+
await ctx.shell.run("rr", ["x", "jscheck", "tscheck"]);
|
|
13
13
|
});
|
|
14
14
|
}
|
|
@@ -34,7 +34,9 @@ async function typecheckAt({ dir, scripts, log, shell, run }: TypecheckAtOptions
|
|
|
34
34
|
const preScript = getPreScript(scripts);
|
|
35
35
|
if (preScript) {
|
|
36
36
|
log.start(`Running pre-script: ${preScript}`);
|
|
37
|
-
|
|
37
|
+
// Pre-scripts come from package.json and may contain shell features
|
|
38
|
+
// (`&&`, pipes, env-var substitution) — run them through `/bin/sh -c`.
|
|
39
|
+
await shellAt.run(preScript, [], { shell: true });
|
|
38
40
|
log.success("Pre-script completed");
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -71,11 +73,10 @@ export function createTsCheckCommand(ctx: Context) {
|
|
|
71
73
|
const runTypecheck = async (shell: ShellService) => {
|
|
72
74
|
if (config.future?.oxc) {
|
|
73
75
|
const oxlint = new OxlintService(shell);
|
|
74
|
-
await oxlint.exec(
|
|
76
|
+
await oxlint.exec(["--type-aware", "--type-check", "--report-unused-disable-directives"]);
|
|
75
77
|
} else {
|
|
76
78
|
const tsc = new TscService(shell);
|
|
77
|
-
await tsc.exec(
|
|
78
|
-
// await shell.$`tsc --noEmit`;
|
|
79
|
+
await tsc.exec(["--noEmit"]);
|
|
79
80
|
}
|
|
80
81
|
};
|
|
81
82
|
|
|
@@ -7,8 +7,7 @@ export function createXCommand(ctx: Context) {
|
|
|
7
7
|
.description("Run multiple rr subcommands concurrently (e.g. `rr x jsc tsc`).")
|
|
8
8
|
.argument("<cmds...>", "rr subcommands to execute concurrently")
|
|
9
9
|
.action(async function runXAction(cmds: string[]) {
|
|
10
|
-
const
|
|
11
|
-
const results = await Promise.allSettled(cmds.map((cmd) => $`rr ${cmd}`));
|
|
10
|
+
const results = await Promise.allSettled(cmds.map((cmd) => ctx.shell.run("rr", [cmd])));
|
|
12
11
|
if (results.some((r) => r.status === "rejected")) {
|
|
13
12
|
process.exitCode = 1;
|
|
14
13
|
}
|
package/src/services/biome.ts
CHANGED
|
@@ -1,48 +1,38 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isCI, type ShellService } from "@vlandoss/clibuddy";
|
|
1
|
+
import { isCI, resolveBinPath, type ShellService } from "@vlandoss/clibuddy";
|
|
3
2
|
import { TOOL_LABELS } from "#src/program/ui.ts";
|
|
4
3
|
import type { FormatOptions, Formatter, Linter, LintOptions, StaticChecker, StaticCheckerOptions } from "#src/types/tool.ts";
|
|
5
4
|
import { ToolService } from "./tool.ts";
|
|
6
5
|
|
|
6
|
+
const COMMON_FLAGS = ["--colors=force", "--no-errors-on-unmatched"];
|
|
7
|
+
|
|
7
8
|
export class BiomeService extends ToolService implements Formatter, Linter, StaticChecker {
|
|
8
9
|
constructor(shellService: ShellService) {
|
|
9
10
|
super({ bin: "biome", ui: TOOL_LABELS.BIOME, shellService });
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
override getBinDir() {
|
|
13
|
-
|
|
14
|
-
return require.resolve("@biomejs/biome/bin/biome");
|
|
14
|
+
return resolveBinPath("@biomejs/biome", { from: import.meta.url, binName: "biome" });
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
async format(options: FormatOptions) {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
await this.exec(`${commonOptions} --fix`);
|
|
22
|
-
} else {
|
|
23
|
-
await this.exec(`${commonOptions}`);
|
|
24
|
-
}
|
|
18
|
+
const args = ["format", ...COMMON_FLAGS];
|
|
19
|
+
if (options.fix) args.push("--fix");
|
|
20
|
+
await this.exec(args);
|
|
25
21
|
}
|
|
26
22
|
|
|
27
23
|
async lint(options: LintOptions) {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
await this.exec(`${commonOptions} --fix --unsafe`);
|
|
32
|
-
} else {
|
|
33
|
-
await this.exec(`${commonOptions}`);
|
|
34
|
-
}
|
|
24
|
+
const args = ["check", ...COMMON_FLAGS, "--formatter-enabled=false"];
|
|
25
|
+
if (options.fix) args.push("--fix", "--unsafe");
|
|
26
|
+
await this.exec(args);
|
|
35
27
|
}
|
|
36
28
|
|
|
37
29
|
async check(options: StaticCheckerOptions): Promise<void> {
|
|
38
|
-
const commonOptions = (cmd = "check") => `${cmd} --colors=force --no-errors-on-unmatched`;
|
|
39
|
-
|
|
40
30
|
if (options.fix) {
|
|
41
|
-
await this.exec(
|
|
31
|
+
await this.exec(["check", ...COMMON_FLAGS, "--fix"]);
|
|
42
32
|
} else if (options.fixStaged) {
|
|
43
|
-
await this.exec(
|
|
33
|
+
await this.exec(["check", ...COMMON_FLAGS, "--fix", "--staged"]);
|
|
44
34
|
} else {
|
|
45
|
-
await this.exec(
|
|
35
|
+
await this.exec([isCI ? "ci" : "check", ...COMMON_FLAGS]);
|
|
46
36
|
}
|
|
47
37
|
}
|
|
48
38
|
}
|
package/src/services/ctx.ts
CHANGED
|
@@ -32,10 +32,7 @@ export async function createContext(binDir: string): Promise<Context> {
|
|
|
32
32
|
debug("app pkg info: %O", appPkg.info());
|
|
33
33
|
debug("bin pkg info: %O", binPkg.info());
|
|
34
34
|
|
|
35
|
-
const shell = createShellService(
|
|
36
|
-
localBaseBinPath: [binDir],
|
|
37
|
-
stdio: "inherit",
|
|
38
|
-
});
|
|
35
|
+
const shell = createShellService();
|
|
39
36
|
|
|
40
37
|
debug("shell service options: %O", shell.options);
|
|
41
38
|
|
package/src/services/oxfmt.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { resolveBinPath, type ShellService } from "@vlandoss/clibuddy";
|
|
2
2
|
import { TOOL_LABELS } from "#src/program/ui.ts";
|
|
3
3
|
import type { FormatOptions, Formatter } from "#src/types/tool.ts";
|
|
4
4
|
import { ToolService } from "./tool.ts";
|
|
@@ -9,16 +9,10 @@ export class OxfmtService extends ToolService implements Formatter {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
override getBinDir() {
|
|
12
|
-
return
|
|
12
|
+
return resolveBinPath("oxfmt", { from: import.meta.url });
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
async format(options: FormatOptions) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (options.fix) {
|
|
19
|
-
await this.exec(`${commonOptions} --fix`);
|
|
20
|
-
} else {
|
|
21
|
-
await this.exec(`${commonOptions} --check`);
|
|
22
|
-
}
|
|
16
|
+
await this.exec(["--no-error-on-unmatched-pattern", options.fix ? "--fix" : "--check"]);
|
|
23
17
|
}
|
|
24
18
|
}
|
package/src/services/oxlint.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { resolveBinPath, type ShellService } from "@vlandoss/clibuddy";
|
|
2
2
|
import { TOOL_LABELS } from "#src/program/ui.ts";
|
|
3
3
|
import type { Linter, LintOptions } from "#src/types/tool.ts";
|
|
4
4
|
import { ToolService } from "./tool.ts";
|
|
@@ -9,16 +9,10 @@ export class OxlintService extends ToolService implements Linter {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
override getBinDir() {
|
|
12
|
-
return
|
|
12
|
+
return resolveBinPath("oxlint", { from: import.meta.url });
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
async lint(options: LintOptions) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (options.fix) {
|
|
19
|
-
await this.exec(`${commonOptions} --fix`);
|
|
20
|
-
} else {
|
|
21
|
-
await this.exec(`${commonOptions} --check`);
|
|
22
|
-
}
|
|
16
|
+
await this.exec(["--report-unused-disable-directives", options.fix ? "--fix" : "--check"]);
|
|
23
17
|
}
|
|
24
18
|
}
|
package/src/services/tool.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
1
|
import type { ShellService } from "@vlandoss/clibuddy";
|
|
4
|
-
import memoize from "memoize";
|
|
5
2
|
import type { DoctorResult } from "#src/types/tool.ts";
|
|
6
3
|
|
|
7
4
|
type CreateOptions = {
|
|
@@ -21,51 +18,22 @@ export abstract class ToolService {
|
|
|
21
18
|
this.#shellService = shellService;
|
|
22
19
|
}
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
// Must return an absolute path so we bypass the `node_modules/.bin/<bin>`
|
|
22
|
+
// shims that run-run itself publishes (`tools/biome`, etc) — otherwise
|
|
23
|
+
// calling the friendly name loops back through `rr tools <bin>`.
|
|
24
|
+
abstract getBinDir(): string;
|
|
25
25
|
|
|
26
|
-
async exec(args
|
|
27
|
-
|
|
28
|
-
return this.#run(shell, args);
|
|
26
|
+
async exec(args: string[] = []) {
|
|
27
|
+
return this.#shellService.run(this.getBinDir(), args, { display: this.#bin });
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
async doctor(): Promise<DoctorResult> {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
const output = await this.#run(shell, "--help");
|
|
31
|
+
const output = await this.#shellService.runCaptured(this.getBinDir(), ["--help"], { throwOnError: false });
|
|
35
32
|
const ok = output.exitCode === 0;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
#shell = memoize((cwd?: string) => {
|
|
41
|
-
const preferLocal = this.#getPreferLocal();
|
|
42
|
-
|
|
43
|
-
return this.#shellService.child({
|
|
44
|
-
...(cwd && { cwd }),
|
|
45
|
-
...(preferLocal && { preferLocal }),
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
#run(shell: ShellService, args?: string | string[]) {
|
|
50
|
-
if (!args) {
|
|
51
|
-
return shell.$`${this.#bin}`;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return shell.$`${this.#bin} ${typeof args === "string" ? args : args.join(" ")}`;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
#getPreferLocal() {
|
|
58
|
-
if (!this.getBinDir) {
|
|
59
|
-
return undefined;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
const binPath = this.getBinDir();
|
|
64
|
-
const isDir = fs.statSync(binPath).isDirectory();
|
|
65
|
-
return isDir ? binPath : path.dirname(binPath);
|
|
66
|
-
} catch {
|
|
67
|
-
return undefined;
|
|
68
|
-
}
|
|
33
|
+
return {
|
|
34
|
+
ok,
|
|
35
|
+
output: { stdout: output.stdout, stderr: output.stderr, exitCode: output.exitCode },
|
|
36
|
+
};
|
|
69
37
|
}
|
|
70
38
|
|
|
71
39
|
get bin() {
|
package/src/services/tsc.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { resolveBinPath, type ShellService } from "@vlandoss/clibuddy";
|
|
2
2
|
import { TOOL_LABELS } from "#src/program/ui.ts";
|
|
3
3
|
import { ToolService } from "./tool.ts";
|
|
4
4
|
|
|
@@ -6,4 +6,8 @@ export class TscService extends ToolService {
|
|
|
6
6
|
constructor(shellService: ShellService) {
|
|
7
7
|
super({ bin: "tsc", ui: TOOL_LABELS.TSC, shellService });
|
|
8
8
|
}
|
|
9
|
+
|
|
10
|
+
override getBinDir() {
|
|
11
|
+
return resolveBinPath("typescript", { from: import.meta.url, binName: "tsc" });
|
|
12
|
+
}
|
|
9
13
|
}
|
package/src/services/tsdown.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { resolveBinPath, type ShellService } from "@vlandoss/clibuddy";
|
|
2
2
|
import { TOOL_LABELS } from "#src/program/ui.ts";
|
|
3
3
|
import { ToolService } from "./tool.ts";
|
|
4
4
|
|
|
@@ -7,6 +7,10 @@ export class TsdownService extends ToolService {
|
|
|
7
7
|
super({ bin: "tsdown", ui: TOOL_LABELS.TSDOWN, shellService });
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
override getBinDir() {
|
|
11
|
+
return resolveBinPath("tsdown", { from: import.meta.url });
|
|
12
|
+
}
|
|
13
|
+
|
|
10
14
|
async buildLib() {
|
|
11
15
|
await this.exec();
|
|
12
16
|
}
|