Skip to content

Commit 22cea07

Browse files
authored
chore(scripts): multi-commands for cli dispatcher (#1712)
1 parent 58c7732 commit 22cea07

File tree

2 files changed

+63
-61
lines changed

2 files changed

+63
-61
lines changed

scripts/cli-dispatcher/index.js

Lines changed: 38 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
#!/usr/bin/env node
22

3-
const fs = require("fs");
43
const path = require("path");
54
const readline = require("readline");
65

76
const findFolders = require("./lib/findFolders");
87
const findScripts = require("./lib/findScripts");
98
const Package = require("./lib/Package");
9+
const { listFolders } = require("../utils/list-folders");
1010

1111
/**
1212
* This script takes your command line arguments and infers the
1313
* package in which to execute them.
1414
*
15-
* It is supposed to save time moving among packages folders
15+
* It is supposed to save time moving among packages/private folders
1616
* for building and running other test commands.
1717
*/
1818
async function main() {
@@ -21,42 +21,32 @@ async function main() {
2121
const root = path.join(__dirname, "..", "..");
2222
const argv = process.argv;
2323

24-
const packages = fs.readdirSync(path.join(root, "packages"));
25-
const private = fs.readdirSync(path.join(root, "private"));
24+
const packages = listFolders(path.join(root, "packages"));
25+
const _private = listFolders(path.join(root, "private"));
2626

2727
const allPackages = [
2828
...packages.map((p) => new Package(p, path.join(root, "packages", p))),
29-
...private.map((p) => new Package(p, path.join(root, "private", p))),
29+
..._private.map((p) => new Package(p, path.join(root, "private", p))),
3030
];
3131

3232
const [node, dispatcher, ...rest] = argv;
3333
const flags = rest.filter((f) => f.startsWith("--"));
3434
const options = {
35-
dry: flags.includes("--dry"),
3635
help: flags.includes("--help") || rest.length === 0,
37-
confirm: flags.includes("--c"),
3836
};
3937

4038
if (options.help) {
4139
console.info(`
4240
Usage:
4341
b [package query words] - [command query words]
44-
b cor - b t
42+
b cor - build,test
4543
4644
matches to:
47-
(cd packages/core && yarn build:types)
45+
(cd packages/core && yarn build && yarn test)
4846
4947
Query words are substrings that match against the package name and npm scripts.
5048
The substrings must appear in order for a match.
5149
Match priority goes to whole-word matching and initial matching.
52-
53-
Options:
54-
--dry
55-
dry run with no command execution.
56-
--help
57-
show this message.
58-
--c
59-
ask for confirmation before executing command.
6050
`);
6151
return 0;
6252
}
@@ -65,6 +55,10 @@ async function main() {
6555
const separatorIndex = rest.indexOf("-") !== -1 ? rest.indexOf("-") : rest.length;
6656
const query = nonFlags.slice(0, separatorIndex);
6757
const commands = nonFlags.slice(separatorIndex + 1);
58+
const multiCommands = commands
59+
.join(" ")
60+
.split(/,\s?/)
61+
.map((c) => c.split(" "));
6862

6963
const matchedPackages = findFolders(allPackages, ...query);
7064

@@ -80,59 +74,42 @@ async function main() {
8074
);
8175

8276
const [target] = matchedPackages;
83-
8477
const targetPkgJson = require(path.join(target.location, "package.json"));
85-
const matchedScripts = findScripts(Object.keys(targetPkgJson.scripts || {}), ...commands);
86-
const [script] = matchedScripts;
87-
88-
if (commands.length === 0) {
89-
console.info("No commands entered");
90-
return 0;
91-
}
9278

93-
if (matchedScripts.length === 0) {
94-
console.error("No matching scripts for command query:", commands);
95-
return 0;
96-
}
79+
for (const commands of multiCommands) {
80+
const matchedScripts = findScripts(Object.keys(targetPkgJson.scripts || {}), ...commands);
9781

98-
console.log("commands:", ...commands);
99-
console.log("matched commands:", matchedScripts);
82+
if (commands.length === 0) {
83+
console.info("No commands entered");
84+
return 0;
85+
}
10086

101-
const command = `yarn ${script} in ${target.location}`;
87+
if (matchedScripts.length === 0) {
88+
console.error("No matching scripts for command query:", commands);
89+
return 0;
90+
}
10291

103-
if (options.dry) {
104-
console.log("DRYRUN:", command);
105-
return 0;
92+
console.log("commands:", ...commands);
93+
console.log("matched commands:", matchedScripts);
10694
}
10795

108-
const execute = async () => {
109-
const { spawnProcess } = require("../utils/spawn-process");
110-
console.info("Running:", "yarn", script);
111-
console.info("Location:", target.location);
112-
await spawnProcess("yarn", [script], {
113-
cwd: target.location,
114-
stdio: "inherit",
115-
});
116-
return;
117-
};
118-
119-
if (options.confirm) {
120-
const rl = readline.createInterface({
121-
input: process.stdin,
122-
output: process.stdout,
123-
});
124-
125-
rl.question(`run script "${script}" in ${target.location} (y)/n?:`, async (confirm) => {
126-
if (confirm.toLowerCase().trim() === "y" || confirm === "") {
127-
await execute();
128-
}
129-
rl.close();
130-
});
131-
return 0;
96+
for (const commands of multiCommands) {
97+
const matchedScripts = findScripts(Object.keys(targetPkgJson.scripts || {}), ...commands);
98+
const [script] = matchedScripts;
99+
100+
const execute = async () => {
101+
const { spawnProcess } = require("../utils/spawn-process");
102+
console.info("Running:", "yarn", script);
103+
console.info("Location:", target.location);
104+
await spawnProcess("yarn", [script], {
105+
cwd: target.location,
106+
stdio: "inherit",
107+
});
108+
};
109+
110+
await execute();
132111
}
133112

134-
await execute();
135-
136113
return 0;
137114
}
138115

scripts/utils/list-folders.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const fs = require("node:fs");
2+
const path = require("node:path");
3+
4+
/**
5+
* @param dir - directory.
6+
* @param basenameOnly - if true, return only the basename of the subdirectories
7+
* @returns {string[]} list of full-paths of subdirectories (not files) in the given directory.
8+
*/
9+
function listFolders(dir, basenameOnly = true) {
10+
const folders = [];
11+
for (const fileSystemEntry of fs.readdirSync(dir, { withFileTypes: true })) {
12+
if (fileSystemEntry.isDirectory()) {
13+
if (basenameOnly) {
14+
folders.push(fileSystemEntry.name);
15+
} else {
16+
folders.push(path.join(dir, fileSystemEntry.name));
17+
}
18+
}
19+
}
20+
return folders;
21+
}
22+
23+
module.exports = {
24+
listFolders,
25+
};

0 commit comments

Comments
 (0)