@vlandoss/run-run 0.0.11 โ†’ 0.0.12

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.0.11",
3
+ "version": "0.0.12",
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": {
@@ -31,6 +31,7 @@
31
31
  "commander": "13.1.0",
32
32
  "glob": "^11.0.2",
33
33
  "is-ci": "4.1.0",
34
+ "memoize": "^10.2.0",
34
35
  "rimraf": "6.0.1",
35
36
  "typescript": "5.8.2",
36
37
  "@vlandoss/clibuddy": "0.0.5",
@@ -1,6 +1,6 @@
1
1
  // Bun Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`should match command: "help" 1`] = `
3
+ exports[`should match all root commands: root-command-help 1`] = `
4
4
  "๐ŸฆŠ R U N - R U N: The CLI toolbox to fullstack common scripts in Variable Land ๐Ÿ‘Š
5
5
 
6
6
  Usage: rr|run-run [options] <command...>
@@ -16,6 +16,8 @@ Commands:
16
16
  tsc|typecheck check if TypeScript code is well typed ๐ŸŽจ
17
17
  clean [options] delete dirty folders or files such as
18
18
  node_modules, etc ๐Ÿ—‘๏ธ
19
+ pkgs|packages [options] list unique affected packages from list of files
20
+ ๐Ÿ“ฆ
19
21
  help [command] display help for command
20
22
 
21
23
  Acknowledgment:
@@ -27,7 +29,7 @@ Acknowledgment:
27
29
  "
28
30
  `;
29
31
 
30
- exports[`should match command: "--help" 1`] = `
32
+ exports[`should match all root commands: root-command---help 1`] = `
31
33
  "๐ŸฆŠ R U N - R U N: The CLI toolbox to fullstack common scripts in Variable Land ๐Ÿ‘Š
32
34
 
33
35
  Usage: rr|run-run [options] <command...>
@@ -43,6 +45,8 @@ Commands:
43
45
  tsc|typecheck check if TypeScript code is well typed ๐ŸŽจ
44
46
  clean [options] delete dirty folders or files such as
45
47
  node_modules, etc ๐Ÿ—‘๏ธ
48
+ pkgs|packages [options] list unique affected packages from list of files
49
+ ๐Ÿ“ฆ
46
50
  help [command] display help for command
47
51
 
48
52
  Acknowledgment:
@@ -54,17 +58,17 @@ Acknowledgment:
54
58
  "
55
59
  `;
56
60
 
57
- exports[`should match command: "--version" 1`] = `
61
+ exports[`should match all root commands: root-command---version 1`] = `
58
62
  "0.0.0-test
59
63
  "
60
64
  `;
61
65
 
62
- exports[`should match command: "-v" 1`] = `
66
+ exports[`should match all root commands: root-command--v 1`] = `
63
67
  "0.0.0-test
64
68
  "
65
69
  `;
66
70
 
67
- exports[`should match help message for command "run" 1`] = `
71
+ exports[`should match help messages for all commands: help-command-run 1`] = `
68
72
  "Usage: rr run [options] <cmds...>
69
73
 
70
74
  Arguments:
@@ -75,7 +79,7 @@ Options:
75
79
  "
76
80
  `;
77
81
 
78
- exports[`should match help message for command "check" 1`] = `
82
+ exports[`should match help messages for all commands: help-command-check 1`] = `
79
83
  "Usage: rr check|test:static [options]
80
84
 
81
85
  check format and lint issues ๐Ÿ”
@@ -89,7 +93,7 @@ Under the hood, this command uses the biome CLI to check the code.
89
93
  "
90
94
  `;
91
95
 
92
- exports[`should match help message for command "lint" 1`] = `
96
+ exports[`should match help messages for all commands: help-command-lint 1`] = `
93
97
  "Usage: rr lint [options]
94
98
 
95
99
  lint the code ๐Ÿงน
@@ -103,7 +107,7 @@ Under the hood, this command uses the biome CLI to lint the code.
103
107
  "
104
108
  `;
105
109
 
106
- exports[`should match help message for command "fmt" 1`] = `
110
+ exports[`should match help messages for all commands: help-command-fmt 1`] = `
107
111
  "Usage: rr fmt|format [options]
108
112
 
109
113
  format the code ๐ŸŽจ
@@ -117,7 +121,7 @@ Under the hood, this command uses the biome CLI to format the code.
117
121
  "
118
122
  `;
119
123
 
120
- exports[`should match help message for command "tsc" 1`] = `
124
+ exports[`should match help messages for all commands: help-command-tsc 1`] = `
121
125
  "Usage: rr tsc|typecheck [options]
122
126
 
123
127
  check if TypeScript code is well typed ๐ŸŽจ
@@ -129,7 +133,7 @@ Under the hood, this command uses the TypeScript CLI to check the code.
129
133
  "
130
134
  `;
131
135
 
132
- exports[`should match help message for command "clean" 1`] = `
136
+ exports[`should match help messages for all commands: help-command-clean 1`] = `
133
137
  "Usage: rr clean [options]
134
138
 
135
139
  delete dirty folders or files such as node_modules, etc ๐Ÿ—‘๏ธ
@@ -143,7 +147,19 @@ Under the hood, this command uses the rimraf.js to delete dirty folders or files
143
147
  "
144
148
  `;
145
149
 
146
- exports[`should match help message for command "tools" 1`] = `
150
+ exports[`should match help messages for all commands: help-command-pkgs 1`] = `
151
+ "Usage: rr pkgs|packages [options]
152
+
153
+ list unique affected packages from list of files ๐Ÿ“ฆ
154
+
155
+ Options:
156
+ --files <files...> list of files to check
157
+ --decorator [type] type of decorator to use (choices: "turbo")
158
+ -h, --help display help for command
159
+ "
160
+ `;
161
+
162
+ exports[`should match help messages for all commands: help-command-tools 1`] = `
147
163
  "Usage: rr tools [options] [command]
148
164
 
149
165
  expose the internal tools ๐Ÿ› ๏ธ
@@ -1,5 +1,5 @@
1
1
  import { afterEach, expect, test } from "bun:test";
2
- import { createTestProgram, execCli, mocked } from "test/helpers";
2
+ import { createTestProgram, execCli, mocked } from "#test/helpers";
3
3
 
4
4
  const { program, ctx } = await createTestProgram();
5
5
  const $ = ctx.shell.$;
@@ -10,20 +10,29 @@ afterEach(() => {
10
10
  mocked($).mockClear();
11
11
  });
12
12
 
13
- for (const cmd of rootCommands) {
14
- test(`should match command: "${cmd}"`, async () => {
15
- const { stdout } = await execCli(cmd);
16
-
17
- expect(stdout).toMatchSnapshot();
18
- });
19
- }
20
-
21
- for (const command of program.commands) {
22
- const cmd = command.name();
23
-
24
- test(`should match help message for command "${cmd}"`, async () => {
25
- const { stdout } = await execCli(`${cmd} --help`);
13
+ test("should match all root commands", async () => {
14
+ const results = await Promise.all(
15
+ rootCommands.map(async (cmd) => {
16
+ const { stdout } = await execCli(cmd);
17
+ return { cmd, output: stdout };
18
+ }),
19
+ );
20
+
21
+ for (const { cmd, output } of results) {
22
+ expect(output).toMatchSnapshot(`root-command-${cmd}`);
23
+ }
24
+ });
26
25
 
27
- expect(stdout).toMatchSnapshot();
28
- });
29
- }
26
+ test("should match help messages for all commands", async () => {
27
+ const results = await Promise.all(
28
+ program.commands.map(async (command) => {
29
+ const cmd = command.name();
30
+ const { stdout } = await execCli(`${cmd} --help`);
31
+ return { cmd, output: stdout };
32
+ }),
33
+ );
34
+
35
+ for (const { cmd, output } of results) {
36
+ expect(output).toMatchSnapshot(`help-command-${cmd}`);
37
+ }
38
+ });
@@ -1,7 +1,7 @@
1
1
  import { createCommand } from "commander";
2
2
  import isCI from "is-ci";
3
- import { BiomeService } from "~/services/biome";
4
- import type { Context } from "~/services/ctx";
3
+ import { BiomeService } from "#/services/biome";
4
+ import type { Context } from "#/services/ctx";
5
5
 
6
6
  export function createCheckCommand(ctx: Context) {
7
7
  return createCommand("check")
@@ -2,7 +2,7 @@ import { cwd } from "@vlandoss/clibuddy";
2
2
  import { createCommand } from "commander";
3
3
  import { type GlobOptions, glob } from "glob";
4
4
  import { rimraf } from "rimraf";
5
- import { logger } from "~/services/logger";
5
+ import { logger } from "#/services/logger";
6
6
 
7
7
  type Options = {
8
8
  onlyDist: boolean;
@@ -1,6 +1,6 @@
1
1
  import { createCommand } from "commander";
2
- import { BiomeService } from "~/services/biome";
3
- import type { Context } from "~/services/ctx";
2
+ import { BiomeService } from "#/services/biome";
3
+ import type { Context } from "#/services/ctx";
4
4
 
5
5
  export function createFormatCommand(ctx: Context) {
6
6
  return createCommand("fmt")
@@ -1,6 +1,6 @@
1
1
  import { createCommand } from "commander";
2
- import { BiomeService } from "~/services/biome";
3
- import type { Context } from "~/services/ctx";
2
+ import { BiomeService } from "#/services/biome";
3
+ import type { Context } from "#/services/ctx";
4
4
 
5
5
  export function createLintCommand(ctx: Context) {
6
6
  return createCommand("lint")
@@ -0,0 +1,75 @@
1
+ import path from "node:path";
2
+ import { type Command, createCommand, Option } from "commander";
3
+ import memoize from "memoize";
4
+ import type { Context } from "#/services/ctx";
5
+ import { logger } from "#/services/logger";
6
+
7
+ // Currently only "turbo" is supported, but this can be extended in the future
8
+ const decorators = ["turbo"] as const;
9
+
10
+ type Options = {
11
+ files: string[];
12
+ decorator?: (typeof decorators)[number];
13
+ };
14
+
15
+ export function createPkgsCommand(ctx: Context) {
16
+ return createCommand("pkgs")
17
+ .alias("packages")
18
+ .description("list unique affected packages from list of files ๐Ÿ“ฆ")
19
+ .addOption(new Option("--files <files...>", "list of files to check"))
20
+ .addOption(new Option("--decorator [type]", "type of decorator to use").choices(decorators))
21
+ .action(async function pkgsAction({ files, decorator }: Options, cmd: Command) {
22
+ const { appPkg } = ctx;
23
+
24
+ if (!appPkg.isMonorepo()) {
25
+ const cmdName = cmd.parent?.args[0] ?? cmd.args[0] ?? cmd.name();
26
+ logger.error(`The \`${cmdName}\` command can only be run in a monorepo.`);
27
+ return process.exit(1);
28
+ }
29
+
30
+ const projects = await appPkg.getWorkspaceProjects();
31
+
32
+ const getRelativeRootDir = memoize((rootDir: string) => {
33
+ const appDir = appPkg.dirPath;
34
+
35
+ if (!path.isAbsolute(rootDir)) {
36
+ return rootDir;
37
+ }
38
+
39
+ return path.relative(appDir, rootDir);
40
+ });
41
+
42
+ function getPackageForFile(filePath: string) {
43
+ for (const project of projects) {
44
+ const relativeRootDir = getRelativeRootDir(project.rootDir);
45
+
46
+ if (filePath.startsWith(relativeRootDir)) {
47
+ return project;
48
+ }
49
+ }
50
+
51
+ return null;
52
+ }
53
+
54
+ const uniquePkgsNames = new Set<string>();
55
+
56
+ files.forEach((file) => {
57
+ const pkg = getPackageForFile(file);
58
+ if (pkg?.manifest.name) {
59
+ uniquePkgsNames.add(pkg.manifest.name);
60
+ }
61
+ });
62
+
63
+ if (!uniquePkgsNames.size) {
64
+ return;
65
+ }
66
+
67
+ const pkgsNames = Array.from(uniquePkgsNames);
68
+
69
+ if (decorator === "turbo") {
70
+ console.log(...pkgsNames.map((name) => `--filter=...${name}`));
71
+ } else {
72
+ console.log(...pkgsNames);
73
+ }
74
+ });
75
+ }
@@ -1,5 +1,5 @@
1
1
  import { createCommand } from "commander";
2
- import type { Context } from "~/services/ctx";
2
+ import type { Context } from "#/services/ctx";
3
3
 
4
4
  export function createRunCommand(ctx: Context) {
5
5
  const program = createCommand("run")
@@ -1,6 +1,6 @@
1
1
  import { createCommand } from "commander";
2
- import { BiomeService } from "~/services/biome";
3
- import type { Context } from "~/services/ctx";
2
+ import { BiomeService } from "#/services/biome";
3
+ import type { Context } from "#/services/ctx";
4
4
 
5
5
  function createToolCommand(toolBin: string) {
6
6
  // biome-ignore format: I prefer multi-line here
@@ -1,7 +1,7 @@
1
1
  import type { Project } from "@vlandoss/clibuddy";
2
2
  import { createCommand } from "commander";
3
- import type { Context } from "~/services/ctx";
4
- import { logger } from "~/services/logger";
3
+ import type { Context } from "#/services/ctx";
4
+ import { logger } from "#/services/logger";
5
5
 
6
6
  export function createTypecheckCommand(ctx: Context) {
7
7
  return createCommand("tsc")
@@ -1,10 +1,11 @@
1
1
  import { getVersion } from "@vlandoss/clibuddy";
2
2
  import { createCommand } from "commander";
3
- import { createContext } from "~/services/ctx";
3
+ import { createContext } from "#/services/ctx";
4
4
  import { createCheckCommand } from "./commands/check";
5
5
  import { createCleanCommand } from "./commands/clean";
6
6
  import { createFormatCommand } from "./commands/format";
7
7
  import { createLintCommand } from "./commands/lint";
8
+ import { createPkgsCommand } from "./commands/pkgs";
8
9
  import { createRunCommand } from "./commands/run";
9
10
  import { createToolsCommand } from "./commands/tools";
10
11
  import { createTypecheckCommand } from "./commands/typecheck";
@@ -31,6 +32,7 @@ export async function createProgram(options: Options) {
31
32
  .addCommand(createFormatCommand(ctx))
32
33
  .addCommand(createTypecheckCommand(ctx))
33
34
  .addCommand(createCleanCommand())
35
+ .addCommand(createPkgsCommand(ctx))
34
36
  .addCommand(createToolsCommand(ctx), {
35
37
  hidden: true,
36
38
  });
@@ -1,5 +1,5 @@
1
1
  import type { ShellService } from "@vlandoss/clibuddy";
2
- import { gracefullBinDir } from "~/utils/gracefullBinDir";
2
+ import { gracefullBinDir } from "#/utils/gracefullBinDir";
3
3
  import type { ToolService } from "./models";
4
4
 
5
5
  export class BiomeService implements ToolService {
@@ -1,6 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { logger } from "~/services/logger";
3
+ import { logger } from "#/services/logger";
4
4
 
5
5
  export function gracefullBinDir(binPathResolver: () => string) {
6
6
  try {
package/tsconfig.json CHANGED
@@ -3,8 +3,8 @@
3
3
  "compilerOptions": {
4
4
  "baseUrl": ".",
5
5
  "paths": {
6
- "~/*": ["./src/*"],
7
- "test/*": ["./test/*"],
6
+ "#/*": ["./src/*"],
7
+ "#test/*": ["./test/*"],
8
8
  "@vlandoss/*": ["../../packages/*/src"]
9
9
  }
10
10
  }