@vlandoss/run-run 0.6.1 → 0.6.2-git-c337c44.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vlandoss/run-run",
3
- "version": "0.6.1",
3
+ "version": "0.6.2-git-c337c44.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": {
@@ -12,7 +12,10 @@
12
12
  "directory": "packages/run-run"
13
13
  },
14
14
  "license": "MIT",
15
- "author": "rcrd <rcrd@variable.land>",
15
+ "author": {
16
+ "name": "rcrd",
17
+ "email": "rcrd@variable.land"
18
+ },
16
19
  "type": "module",
17
20
  "imports": {
18
21
  "#src/*": "./src/*",
@@ -53,6 +56,8 @@
53
56
  "dependencies": {
54
57
  "@biomejs/biome": "2.4.4",
55
58
  "@usage-spec/commander": "1.1.0",
59
+ "@vlandoss/clibuddy": "0.6.0",
60
+ "@vlandoss/loggy": "0.2.0",
56
61
  "commander": "14.0.3",
57
62
  "glob": "13.0.6",
58
63
  "lilconfig": "3.1.3",
@@ -62,13 +67,13 @@
62
67
  "oxlint-tsgolint": "0.15.0",
63
68
  "rimraf": "6.1.3",
64
69
  "tsdown": "0.22.0",
65
- "typescript": "6.0.3",
66
- "@vlandoss/loggy": "0.2.0",
67
- "@vlandoss/clibuddy": "0.6.0"
70
+ "typescript": "6.0.3"
68
71
  },
69
72
  "devDependencies": {
70
73
  "@vlandoss/tsdown-config": "^0.0.1"
71
74
  },
75
+ "readme": "ERROR: No README data found!",
76
+ "_id": "@vlandoss/run-run@0.6.1",
72
77
  "scripts": {
73
78
  "build": "tsdown && pnpm build:kdl",
74
79
  "build:kdl": "./bin --usage > dist/cli.usage.kdl",
@@ -77,4 +82,4 @@
77
82
  "test:integration": "vitest run --project integration",
78
83
  "test:types": "rr tsc"
79
84
  }
80
- }
85
+ }
package/src/run.ts CHANGED
@@ -9,3 +9,5 @@ await run(async () => {
9
9
  const { program } = await createProgram({ binDir: BIN_DIR });
10
10
  await program.parseAsync(process.argv, { from: "node" });
11
11
  }, logger);
12
+
13
+ // dummy change 2
@@ -1,71 +0,0 @@
1
- // @generated by @usage-spec/commander from Commander.js metadata
2
- name rr
3
- bin rr
4
- version "0.6.1"
5
- usage "[options] <command...>"
6
- flag --usage help="print KDL spec for this CLI (https://kdl.dev)"
7
- cmd completion help="print shell completion script 🐚 (usage)" {
8
- long_help "Prints a shell completion script for rr. Add to your shell rc file:\n\n bash: eval \"$(rr completion bash)\"\n zsh: eval \"$(rr completion zsh)\"\n fish: rr completion fish | source"
9
- arg <shell> help="target shell" {
10
- choices bash zsh fish
11
- }
12
- }
13
- cmd build:lib help="build a ts library 🏗️ (tsdown)" {
14
- long_help "Compiles TypeScript code into JavaScript and generates type declaration files, making it ready for distribution."
15
- cmd doctor help="check if the underlying tool is working correctly"
16
- }
17
- cmd jsc help="check format and lint 🔍 (biome)" {
18
- alias jscheck
19
- long_help "Checks the code for formatting and linting issues, ensuring it adheres to the defined style and quality standards."
20
- flag --fix help="try to fix issues automatically"
21
- flag --fix-staged help="try to fix staged files only"
22
- cmd doctor help="check if the underlying tool is working correctly"
23
- }
24
- cmd tsc help="check typescript errors 📐 (tsc)" {
25
- alias tscheck
26
- long_help "Checks the TypeScript code for type errors, ensuring that the code adheres to the defined type constraints and helps catch potential issues before runtime."
27
- cmd doctor help="check if the underlying tool is working correctly"
28
- }
29
- cmd lint help="check & fix lint errors 🔍 (biome)" {
30
- long_help "Checks the code for linting issues and optionally fixes them, ensuring it adheres to the defined quality standards."
31
- flag "-c --check" help="check if the code is valid" default=#true
32
- flag --fix help="try to fix all the code"
33
- cmd doctor help="check if the underlying tool is working correctly"
34
- }
35
- cmd format help="check & fix format errors 🎨 (biome)" {
36
- long_help "Checks the code for formatting issues and optionally fixes them, ensuring it adheres to the defined style standards."
37
- flag --fix help="format all the code"
38
- cmd doctor help="check if the underlying tool is working correctly"
39
- }
40
- cmd check help="run static checks 🔬 (run-run)" {
41
- long_help "Runs static checks, including linting, formatting checks, and TypeScript type checking, to ensure code quality and correctness without executing the code."
42
- }
43
- cmd clean help="delete dirty files 🗑️ (rimraf)" {
44
- long_help "Deletes generated files and folders such as 'dist', 'node_modules', and lock files to ensure a clean state."
45
- flag --only-dist help="delete 'dist' folders only"
46
- flag --dry-run help="outputs the paths that would be deleted"
47
- }
48
- cmd pkgs help="list affected packages 📦" {
49
- long_help "Given a list of files, returns the list of affected packages. Useful to run commands only on affected packages."
50
- flag --files help="list of files to check" var=#true {
51
- arg <FILES>
52
- }
53
- flag --decorator help="type of decorator to use" {
54
- arg <DECORATOR> {
55
- choices turbo
56
- }
57
- }
58
- }
59
- cmd x help="run multiple rr subcommands concurrently" {
60
- long_help "Run multiple rr subcommands concurrently (e.g. `rr x jsc tsc`)."
61
- arg <cmds>… help="rr subcommands to execute concurrently" var=#true
62
- }
63
- cmd config help="display the current config 🛠️" {
64
- long_help "Displays the current configuration settings, including their source file path if available."
65
- }
66
- cmd tools hide=#true subcommand_required=#true help="expose the internal tools 🛠️" {
67
- cmd biome
68
- cmd oxfmt
69
- cmd oxlint
70
- cmd tsdown
71
- }
package/dist/config.d.mts DELETED
@@ -1,11 +0,0 @@
1
- //#region src/types/config.d.ts
2
- type UserConfig = {
3
- future?: {
4
- oxc?: boolean;
5
- };
6
- };
7
- //#endregion
8
- //#region src/lib/config.d.ts
9
- declare function defineConfig(config: UserConfig): UserConfig;
10
- //#endregion
11
- export { defineConfig };
package/dist/config.mjs DELETED
@@ -1,6 +0,0 @@
1
- //#region src/lib/config.ts
2
- function defineConfig(config) {
3
- return config;
4
- }
5
- //#endregion
6
- export { defineConfig };
package/dist/run.mjs DELETED
@@ -1,535 +0,0 @@
1
- import path from "node:path";
2
- import { colorize, createPkg, createShellService, cwd, dirnameOf, isCI, palette, resolvePackageBin, run, text } from "@vlandoss/clibuddy";
3
- import { Argument, Option, createCommand } from "commander";
4
- import fs from "node:fs";
5
- import os from "node:os";
6
- import { lilconfig } from "lilconfig";
7
- import { createLoggy } from "@vlandoss/loggy";
8
- import { glob } from "glob";
9
- import { rimraf } from "rimraf";
10
- import memoize from "memoize";
11
- import { generateToStdout } from "@usage-spec/commander";
12
- //#region src/services/logger.ts
13
- const logger = createLoggy({ namespace: "run-run" });
14
- //#endregion
15
- //#region src/services/config.ts
16
- const DEFAULT_CONFIG = { future: { oxc: false } };
17
- var ConfigService = class {
18
- #searcher;
19
- constructor() {
20
- this.#searcher = lilconfig("run-run", {
21
- searchPlaces: ["run-run.config.ts", "run-run.config.mts"],
22
- cache: true,
23
- stopDir: os.homedir(),
24
- loaders: {
25
- ".ts": (filepath) => import(filepath).then((mod) => mod.default),
26
- ".mts": (filepath) => import(filepath).then((mod) => mod.default)
27
- }
28
- });
29
- }
30
- async load() {
31
- const debug = logger.subdebug("load-config");
32
- const searchResult = await this.#searcher.search();
33
- if (!searchResult || searchResult?.isEmpty) {
34
- debug("loaded default config: %O", DEFAULT_CONFIG);
35
- return {
36
- config: DEFAULT_CONFIG,
37
- meta: {
38
- isDefault: true,
39
- filepath: void 0
40
- }
41
- };
42
- }
43
- const config = searchResult.config;
44
- debug("loaded config: %O", config);
45
- debug("config file: %s", searchResult.filepath);
46
- return {
47
- config,
48
- meta: {
49
- isDefault: false,
50
- filepath: searchResult.filepath
51
- }
52
- };
53
- }
54
- };
55
- //#endregion
56
- //#region src/services/ctx.ts
57
- async function createContext(binDir) {
58
- const debug = logger.subdebug("create-context");
59
- const binPath = fs.realpathSync(binDir);
60
- debug("bin path:", binPath);
61
- debug("process cwd:", process.cwd());
62
- const [appPkg, binPkg] = await Promise.all([createPkg(cwd), createPkg(binPath)]);
63
- if (!binPkg) throw new Error("Could not find bin package.json");
64
- if (!appPkg) throw new Error("Could not find app package.json");
65
- debug("app pkg info: %O", appPkg.info());
66
- debug("bin pkg info: %O", binPkg.info());
67
- const shell = createShellService();
68
- debug("shell service options: %O", shell.options);
69
- return {
70
- appPkg,
71
- binPkg,
72
- shell,
73
- config: await new ConfigService().load()
74
- };
75
- }
76
- //#endregion
77
- //#region src/program/ui.ts
78
- const CREDITS_TEXT = `\nAcknowledgment:
79
- - kcd-scripts: for main inspiration
80
- ${palette.link("https://github.com/kentcdodds/kcd-scripts")}
81
-
82
- - peruvian news: in honor to Run Run
83
- ${palette.link("https://es.wikipedia.org/wiki/Run_Run")}`;
84
- const tsdownColor = colorize("#FF7E18");
85
- const biomeColor = colorize("#61A5FA");
86
- const oxlintColor = colorize("#32F3E9");
87
- const oxfmtColor = colorize("#32F3E9");
88
- const tscColor = colorize("#3178C6");
89
- const rimrafColor = colorize("#7C7270");
90
- const runRunColor = colorize("#E8722A");
91
- const usageColor = colorize("#24C55E");
92
- const TOOL_LABELS = {
93
- TSDOWN: tsdownColor("tsdown"),
94
- BIOME: biomeColor("biome"),
95
- OXLINT: oxlintColor("oxlint"),
96
- OXFMT: oxfmtColor("oxfmt"),
97
- TSC: tscColor("tsc"),
98
- RIMRAF: rimrafColor("rimraf"),
99
- RUN_RUN: runRunColor("run-run"),
100
- USAGE: usageColor("usage")
101
- };
102
- function getBannerText(version) {
103
- return `
104
- ${runRunColor(`
105
- ██████╗ ██╗ ██╗███╗ ██╗ ██████╗ ██╗ ██╗███╗ ██╗
106
- ██╔══██╗██║ ██║████╗ ██║ ██╔══██╗██║ ██║████╗ ██║
107
- ██████╔╝██║ ██║██╔██╗ ██║█████╗██████╔╝██║ ██║██╔██╗ ██║
108
- ██╔══██╗██║ ██║██║╚██╗██║╚════╝██╔══██╗██║ ██║██║╚██╗██║
109
- ██║ ██║╚██████╔╝██║ ╚████║ ██║ ██║╚██████╔╝██║ ╚████║
110
- ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ${text.version(version)}
111
- `.trim())}
112
-
113
- 🦊 ${palette.italic(palette.muted("The CLI toolbox for"))} ${text.vland}\n`.trimStart();
114
- }
115
- //#endregion
116
- //#region src/services/tool.ts
117
- var ToolService = class {
118
- #shellService;
119
- #pkg;
120
- #bin;
121
- #ui;
122
- get bin() {
123
- return this.#bin;
124
- }
125
- get ui() {
126
- return this.#ui;
127
- }
128
- get pkg() {
129
- return this.#pkg;
130
- }
131
- constructor({ pkg, bin, ui, shellService }) {
132
- this.#pkg = pkg;
133
- this.#bin = bin ?? pkg;
134
- this.#ui = ui;
135
- this.#shellService = shellService;
136
- }
137
- async getBinDir() {
138
- return resolvePackageBin(this.#pkg, {
139
- from: import.meta.url,
140
- binName: this.#bin
141
- });
142
- }
143
- async exec(args = []) {
144
- return this.#shellService.run(await this.getBinDir(), args, { display: this.#bin });
145
- }
146
- async doctor() {
147
- const output = await this.#shellService.runCaptured(await this.getBinDir(), ["--help"], { throwOnError: false });
148
- return {
149
- ok: output.exitCode === 0,
150
- output: {
151
- stdout: output.stdout,
152
- stderr: output.stderr,
153
- exitCode: output.exitCode
154
- }
155
- };
156
- }
157
- };
158
- //#endregion
159
- //#region src/services/tsdown.ts
160
- var TsdownService = class extends ToolService {
161
- constructor(shellService) {
162
- super({
163
- pkg: "tsdown",
164
- ui: TOOL_LABELS.TSDOWN,
165
- shellService
166
- });
167
- }
168
- async buildLib() {
169
- await this.exec();
170
- }
171
- };
172
- //#endregion
173
- //#region src/program/commands/doctor.ts
174
- function createDoctorSubcommand(service) {
175
- return createCommand("doctor").summary("check if the underlying tool is working correctly").action(async function doctorAction() {
176
- const debug = logger.subdebug("doctor");
177
- const { ok, output } = await service.doctor();
178
- if (ok) {
179
- logger.success(`${service.ui} ok`);
180
- debug("%O", output);
181
- } else {
182
- logger.error(`${service.ui} not working`);
183
- debug("%O", output);
184
- process.exit(output.exitCode ?? 1);
185
- }
186
- });
187
- }
188
- //#endregion
189
- //#region src/program/commands/build-lib.ts
190
- function createBuildLibCommand(ctx) {
191
- const tsdownService = new TsdownService(ctx.shell);
192
- return createCommand("build:lib").summary(`build a ts library 🏗️ (${tsdownService.ui})`).description("Compiles TypeScript code into JavaScript and generates type declaration files, making it ready for distribution.").addCommand(createDoctorSubcommand(tsdownService)).action(async function buildAction() {
193
- await tsdownService.buildLib();
194
- }).addHelpText("afterAll", `\nUnder the hood, this command uses the ${tsdownService.ui} CLI to build the project.`);
195
- }
196
- //#endregion
197
- //#region src/program/commands/check.ts
198
- function createCheckCommand(ctx) {
199
- return createCommand("check").summary(`run static checks 🔬 (${TOOL_LABELS.RUN_RUN})`).description("Runs static checks, including linting, formatting checks, and TypeScript type checking, to ensure code quality and correctness without executing the code.").action(async function checkAction() {
200
- await ctx.shell.run("rr", [
201
- "x",
202
- "jscheck",
203
- "tscheck"
204
- ]);
205
- });
206
- }
207
- //#endregion
208
- //#region src/program/commands/clean.ts
209
- function createCleanCommand() {
210
- return createCommand("clean").summary(`delete dirty files 🗑️ (${TOOL_LABELS.RIMRAF})`).description("Deletes generated files and folders such as 'dist', 'node_modules', and lock files to ensure a clean state.").option("--only-dist", "delete 'dist' folders only").option("--dry-run", "outputs the paths that would be deleted").action(async function cleanCommandAction(options) {
211
- async function run(paths, globOptions) {
212
- if (options.dryRun) {
213
- const toDelete = await glob(paths, globOptions);
214
- logger.info("Paths that would be deleted: %O", toDelete);
215
- return;
216
- }
217
- logger.start("Clean started");
218
- await rimraf(paths, { glob: globOptions });
219
- logger.success("Clean completed");
220
- }
221
- const BUILD_PATHS = ["**/dist"];
222
- const ALL_DIRTY_PATHS = [
223
- "**/.turbo",
224
- "**/node_modules",
225
- "pnpm-lock.yaml",
226
- "bun.lock",
227
- ...BUILD_PATHS
228
- ];
229
- if (options.onlyDist) await run(BUILD_PATHS, {
230
- cwd,
231
- ignore: ["**/node_modules/**"]
232
- });
233
- else await run(ALL_DIRTY_PATHS, { cwd });
234
- }).addHelpText("afterAll", `\nUnder the hood, this command uses ${TOOL_LABELS.RIMRAF} to delete dirty folders or files.`);
235
- }
236
- //#endregion
237
- //#region src/program/commands/completion.ts
238
- const SHELLS = [
239
- "bash",
240
- "zsh",
241
- "fish"
242
- ];
243
- function createCompletionCommand() {
244
- return createCommand("completion").summary(`print shell completion script 🐚 (${TOOL_LABELS.USAGE})`).description(`Prints a shell completion script for rr. Add to your shell rc file:
245
-
246
- bash: eval "$(rr completion bash)"
247
- zsh: eval "$(rr completion zsh)"
248
- fish: rr completion fish | source`).addArgument(new Argument("<shell>", `target shell`).choices(SHELLS)).addHelpText("afterAll", `\nUnder the hood, this command uses ${TOOL_LABELS.USAGE} (https://usage.jdx.dev).
249
- Make sure to have it installed and available in your PATH.`);
250
- }
251
- //#endregion
252
- //#region src/program/commands/config.ts
253
- function createConfigCommand(ctx) {
254
- return createCommand("config").summary("display the current config 🛠️").description("Displays the current configuration settings, including their source file path if available.").action(async function configAction() {
255
- const { config, meta } = ctx.config;
256
- console.log(palette.muted("Config:"));
257
- console.log(config);
258
- console.log(palette.muted(`Loaded from ${meta.filepath ? palette.link(meta.filepath) : "n/a"}`));
259
- });
260
- }
261
- //#endregion
262
- //#region src/services/biome.ts
263
- const COMMON_FLAGS = ["--colors=force", "--no-errors-on-unmatched"];
264
- var BiomeService = class extends ToolService {
265
- constructor(shellService) {
266
- super({
267
- pkg: "@biomejs/biome",
268
- bin: "biome",
269
- ui: TOOL_LABELS.BIOME,
270
- shellService
271
- });
272
- }
273
- async format(options) {
274
- const args = ["format", ...COMMON_FLAGS];
275
- if (options.fix) args.push("--fix");
276
- await this.exec(args);
277
- }
278
- async lint(options) {
279
- const args = [
280
- "check",
281
- ...COMMON_FLAGS,
282
- "--formatter-enabled=false"
283
- ];
284
- if (options.fix) args.push("--fix", "--unsafe");
285
- await this.exec(args);
286
- }
287
- async check(options) {
288
- if (options.fix) await this.exec([
289
- "check",
290
- ...COMMON_FLAGS,
291
- "--fix"
292
- ]);
293
- else if (options.fixStaged) await this.exec([
294
- "check",
295
- ...COMMON_FLAGS,
296
- "--fix",
297
- "--staged"
298
- ]);
299
- else await this.exec([isCI ? "ci" : "check", ...COMMON_FLAGS]);
300
- }
301
- };
302
- //#endregion
303
- //#region src/services/oxfmt.ts
304
- var OxfmtService = class extends ToolService {
305
- constructor(shellService) {
306
- super({
307
- pkg: "oxfmt",
308
- ui: TOOL_LABELS.OXFMT,
309
- shellService
310
- });
311
- }
312
- async format(options) {
313
- await this.exec(["--no-error-on-unmatched-pattern", options.fix ? "--fix" : "--check"]);
314
- }
315
- };
316
- //#endregion
317
- //#region src/program/commands/format.ts
318
- function getToolService$2(ctx) {
319
- const { config } = ctx.config;
320
- if (config.future?.oxc) return new OxfmtService(ctx.shell);
321
- return new BiomeService(ctx.shell);
322
- }
323
- function createFormatCommand(ctx) {
324
- const toolService = getToolService$2(ctx);
325
- return createCommand("format").summary(`check & fix format errors 🎨 (${toolService.ui})`).description("Checks the code for formatting issues and optionally fixes them, ensuring it adheres to the defined style standards.").option("--fix", "format all the code").addCommand(createDoctorSubcommand(toolService)).action(async function formatAction(options) {
326
- await toolService.format(options);
327
- }).addHelpText("afterAll", `\nUnder the hood, this command uses the ${toolService.ui} CLI to format the code.`);
328
- }
329
- //#endregion
330
- //#region src/program/commands/jscheck.ts
331
- function createJsCheckCommand(ctx) {
332
- const checkerService = new BiomeService(ctx.shell);
333
- return createCommand("jsc").alias("jscheck").summary(`check format and lint 🔍 (${checkerService.ui})`).description("Checks the code for formatting and linting issues, ensuring it adheres to the defined style and quality standards.").option("--fix", "try to fix issues automatically").option("--fix-staged", "try to fix staged files only").addCommand(createDoctorSubcommand(checkerService)).action(async function checkAction(options) {
334
- await checkerService.check(options);
335
- }).addHelpText("afterAll", `\nUnder the hood, this command uses the ${checkerService.ui} CLI to check the code.`);
336
- }
337
- //#endregion
338
- //#region src/services/oxlint.ts
339
- var OxlintService = class extends ToolService {
340
- constructor(shellService) {
341
- super({
342
- pkg: "oxlint",
343
- ui: TOOL_LABELS.OXLINT,
344
- shellService
345
- });
346
- }
347
- async lint(options) {
348
- await this.exec(["--report-unused-disable-directives", options.fix ? "--fix" : "--check"]);
349
- }
350
- };
351
- //#endregion
352
- //#region src/program/commands/lint.ts
353
- function getToolService$1(ctx) {
354
- const { config } = ctx.config;
355
- if (config.future?.oxc) return new OxlintService(ctx.shell);
356
- return new BiomeService(ctx.shell);
357
- }
358
- function createLintCommand(ctx) {
359
- const toolService = getToolService$1(ctx);
360
- return createCommand("lint").summary(`check & fix lint errors 🔍 (${toolService.ui})`).description("Checks the code for linting issues and optionally fixes them, ensuring it adheres to the defined quality standards.").option("-c, --check", "check if the code is valid", true).option("--fix", "try to fix all the code").addCommand(createDoctorSubcommand(toolService)).action(async function lintAction(options) {
361
- await toolService.lint(options);
362
- }).addHelpText("afterAll", `\nUnder the hood, this command uses the ${toolService.ui} CLI to lint the code.`);
363
- }
364
- //#endregion
365
- //#region src/program/commands/pkgs.ts
366
- const decorators = ["turbo"];
367
- function createPkgsCommand(ctx) {
368
- return createCommand("pkgs").summary("list affected packages 📦").description("Given a list of files, returns the list of affected packages. Useful to run commands only on affected packages.").addOption(new Option("--files <files...>", "list of files to check")).addOption(new Option("--decorator [type]", "type of decorator to use").choices(decorators)).action(async function pkgsAction({ files, decorator }, cmd) {
369
- const { appPkg } = ctx;
370
- if (!appPkg.isMonorepo()) {
371
- const cmdName = cmd.parent?.args[0] ?? cmd.args[0] ?? cmd.name();
372
- logger.error(`The \`${cmdName}\` command can only be run in a monorepo.`);
373
- return process.exit(1);
374
- }
375
- const projects = await appPkg.getWorkspaceProjects();
376
- const getRelativeRootDir = memoize((rootDir) => {
377
- const appDir = appPkg.dirPath;
378
- if (!path.isAbsolute(rootDir)) return rootDir;
379
- return path.relative(appDir, rootDir);
380
- });
381
- function getPackageForFile(filePath) {
382
- for (const project of projects) {
383
- const relativeRootDir = getRelativeRootDir(project.rootDir);
384
- if (filePath.startsWith(relativeRootDir)) return project;
385
- }
386
- return null;
387
- }
388
- const uniquePkgsNames = /* @__PURE__ */ new Set();
389
- files.forEach((file) => {
390
- const pkg = getPackageForFile(file);
391
- if (pkg?.manifest.name) uniquePkgsNames.add(pkg.manifest.name);
392
- });
393
- if (!uniquePkgsNames.size) return;
394
- const pkgsNames = Array.from(uniquePkgsNames);
395
- if (decorator === "turbo") console.log(...pkgsNames.map((name) => `--filter=...${name}`));
396
- else console.log(...pkgsNames);
397
- });
398
- }
399
- //#endregion
400
- //#region src/program/commands/tools.ts
401
- function getToolService(bin, shell) {
402
- switch (bin) {
403
- case "biome": return new BiomeService(shell);
404
- case "oxfmt": return new OxfmtService(shell);
405
- case "oxlint": return new OxlintService(shell);
406
- case "tsdown": return new TsdownService(shell);
407
- default: throw new Error(`Unknown tool: ${bin}`);
408
- }
409
- }
410
- function createToolCommand(bin, shell) {
411
- const tool = getToolService(bin, shell);
412
- return createCommand(tool.bin).helpCommand(false).helpOption(false).allowExcessArguments(true).allowUnknownOption(true).action(async (_, { args }) => {
413
- await tool.exec(args);
414
- });
415
- }
416
- function createToolsCommand(ctx) {
417
- return createCommand("tools").description("expose the internal tools 🛠️").passThroughOptions().addCommand(createToolCommand("biome", ctx.shell)).addCommand(createToolCommand("oxfmt", ctx.shell)).addCommand(createToolCommand("oxlint", ctx.shell)).addCommand(createToolCommand("tsdown", ctx.shell));
418
- }
419
- //#endregion
420
- //#region src/services/tsc.ts
421
- var TscService = class extends ToolService {
422
- constructor(shellService) {
423
- super({
424
- pkg: "typescript",
425
- bin: "tsc",
426
- ui: TOOL_LABELS.TSC,
427
- shellService
428
- });
429
- }
430
- };
431
- //#endregion
432
- //#region src/program/commands/tscheck.ts
433
- const getPreScript = (scripts) => scripts?.pretsc ?? scripts?.pretypecheck;
434
- async function typecheckAt({ dir, scripts, log, shell, run }) {
435
- let shellAt;
436
- log.debug(`checking types at ${dir}`);
437
- if (cwd === dir) shellAt = shell;
438
- else {
439
- log.debug(`Changing directory to ${dir} for typecheck`);
440
- shellAt = shell.at(dir);
441
- }
442
- try {
443
- const preScript = getPreScript(scripts);
444
- if (preScript) {
445
- log.start(`Running pre-script: ${preScript}`);
446
- await shellAt.run(preScript, [], { shell: true });
447
- log.success("Pre-script completed");
448
- }
449
- log.start("Type checking started");
450
- await run(shellAt);
451
- log.success("Typecheck completed");
452
- } catch (error) {
453
- log.error("Typecheck failed");
454
- throw error;
455
- }
456
- }
457
- function createTsCheckCommand(ctx) {
458
- const { appPkg, shell, config: { config } } = ctx;
459
- const toolUi = config.future?.oxc ? TOOL_LABELS.OXLINT : TOOL_LABELS.TSC;
460
- const doctorService = config.future?.oxc ? new OxlintService(shell) : new TscService(shell);
461
- 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() {
462
- const isTsProject = (dir) => appPkg.hasFile("tsconfig.json", dir);
463
- const runTypecheck = async (shell) => {
464
- if (config.future?.oxc) await new OxlintService(shell).exec([
465
- "--type-aware",
466
- "--type-check",
467
- "--report-unused-disable-directives"
468
- ]);
469
- else await new TscService(shell).exec(["--noEmit"]);
470
- };
471
- if (!appPkg.isMonorepo()) {
472
- if (!isTsProject(appPkg.dirPath)) {
473
- logger.info("No tsconfig.json found, skipping typecheck");
474
- return;
475
- }
476
- await typecheckAt({
477
- shell,
478
- run: runTypecheck,
479
- dir: appPkg.dirPath,
480
- scripts: appPkg.packageJson.scripts,
481
- log: logger
482
- });
483
- return;
484
- }
485
- const tsProjects = (await appPkg.getWorkspaceProjects()).filter((project) => isTsProject(project.rootDir));
486
- if (!tsProjects.length) {
487
- logger.warn("No ts projects found in the monorepo, skipping typecheck");
488
- return;
489
- }
490
- await Promise.all(tsProjects.map((p) => typecheckAt({
491
- shell,
492
- run: runTypecheck,
493
- dir: p.rootDir,
494
- scripts: p.manifest.scripts,
495
- log: logger.child({
496
- tag: p.manifest.name,
497
- namespace: "typecheck"
498
- })
499
- })));
500
- });
501
- }
502
- //#endregion
503
- //#region src/program/commands/usage.ts
504
- function addUsage(program) {
505
- return program.addOption(new Option("--usage", "print KDL spec for this CLI (https://kdl.dev)")).on("option:usage", () => {
506
- generateToStdout(program);
507
- process.exit(0);
508
- });
509
- }
510
- //#endregion
511
- //#region src/program/commands/x.ts
512
- function createXCommand(ctx) {
513
- 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) {
514
- if ((await Promise.allSettled(cmds.map((cmd) => ctx.shell.run("rr", [cmd])))).some((r) => r.status === "rejected")) process.exitCode = 1;
515
- });
516
- }
517
- //#endregion
518
- //#region src/program/index.ts
519
- async function createProgram(options) {
520
- const ctx = await createContext(options.binDir);
521
- const version = ctx.binPkg.version;
522
- return {
523
- program: addUsage(createCommand("rr").usage("[options] <command...>").enablePositionalOptions().version(version, "-v, --version").addHelpText("before", getBannerText(version)).addHelpText("after", CREDITS_TEXT).addCommand(createCompletionCommand()).addCommand(createBuildLibCommand(ctx)).addCommand(createJsCheckCommand(ctx)).addCommand(createTsCheckCommand(ctx)).addCommand(createLintCommand(ctx)).addCommand(createFormatCommand(ctx)).addCommand(createCheckCommand(ctx)).addCommand(createCleanCommand()).addCommand(createPkgsCommand(ctx)).addCommand(createXCommand(ctx)).addCommand(createConfigCommand(ctx)).addCommand(createToolsCommand(ctx), { hidden: true })),
524
- ctx
525
- };
526
- }
527
- //#endregion
528
- //#region src/run.ts
529
- const BIN_DIR = path.dirname(dirnameOf(import.meta));
530
- await run(async () => {
531
- const { program } = await createProgram({ binDir: BIN_DIR });
532
- await program.parseAsync(process.argv, { from: "node" });
533
- }, logger);
534
- //#endregion
535
- export {};
@@ -1 +0,0 @@
1
- export * from "tsdown";
@@ -1,2 +0,0 @@
1
- export * from "tsdown";
2
- export {};