Skip to content

Commit 103745b

Browse files
committed
Just: group just invocations in forwarder and improve logging
1 parent 9267283 commit 103745b

File tree

3 files changed

+70
-62
lines changed

3 files changed

+70
-62
lines changed

misc/just/codeql-test-run.ts

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ import * as path from "path";
33
import * as os from "os";
44
import * as fs from "fs";
55

6+
const vars = {
7+
just: process.env["JUST_EXECUTABLE"] || "just",
8+
error: process.env["JUST_ERROR"] || "error",
9+
cmd_begin: process.env["CMD_BEGIN"] || "",
10+
cmd_end: process.env["CMD_END"] || "",
11+
semmle_code: process.env["SEMMLE_CODE"],
12+
}
13+
614
function invoke(
715
invocation: string[],
816
options: { cwd?: string; log_prefix?: string } = {},
@@ -12,7 +20,7 @@ function invoke(
1220
? `${options.log_prefix} `
1321
: "";
1422
console.log(
15-
`${process.env["CMD_BEGIN"] || ""}${log_prefix}${invocation.join(" ")}${process.env["CMD_END"] || ""}`,
23+
`${vars.cmd_begin}${log_prefix}${invocation.join(" ")}${vars.cmd_end}`,
1624
);
1725
try {
1826
child_process.execFileSync(invocation[0], invocation.slice(1), {
@@ -33,6 +41,12 @@ type Args = {
3341
all: boolean;
3442
};
3543

44+
const old_console_error = console.error;
45+
46+
console.error = (message: string) => {
47+
old_console_error(vars.error + message);
48+
};
49+
3650
function parseArgs(args: Args, argv: string) {
3751
argv.split(/(?<!\\) /)
3852
.map((arg) => arg.replace("\\ ", " "))
@@ -52,23 +66,22 @@ function parseArgs(args: Args, argv: string) {
5266
}
5367

5468
function codeqlTestRun(argv: string[]): number {
55-
const semmle_code = process.env["SEMMLE_CODE"];
5669
const [language, base_args, all_args, extra_args] = argv;
5770
const ram_per_thread = process.platform === "linux" ? 3000 : 2048;
5871
const cpus = os.cpus().length;
5972
let args: Args = {
6073
tests: [],
6174
flags: [`--ram=${ram_per_thread * cpus}`, `-j${cpus}`],
6275
env: [],
63-
codeql: semmle_code ? "build" : "host",
76+
codeql: vars.semmle_code ? "build" : "host",
6477
all: false,
6578
};
6679
parseArgs(args, base_args);
6780
parseArgs(args, extra_args);
6881
if (args.all) {
6982
parseArgs(args, all_args);
7083
}
71-
if (!semmle_code && (args.codeql === "build" || args.codeql === "built")) {
84+
if (!vars.semmle_code && (args.codeql === "build" || args.codeql === "built")) {
7285
console.error(
7386
"Using `--codeql=build` or `--codeql=built` requires working with the internal repository",
7487
);
@@ -79,8 +92,8 @@ function codeqlTestRun(argv: string[]): number {
7992
}
8093
if (args.codeql === "build") {
8194
if (
82-
invoke([process.env["JUST_EXECUTABLE"] || "just", language, "build"], {
83-
cwd: semmle_code,
95+
invoke([vars.just, language, "build"], {
96+
cwd: vars.semmle_code,
8497
}) !== 0
8598
) {
8699
return 1;
@@ -106,32 +119,33 @@ function codeqlTestRun(argv: string[]): number {
106119
}
107120
});
108121
let codeql;
122+
function check_codeql() {
123+
if (!fs.existsSync(codeql)) {
124+
console.error(`CodeQL executable not found: ${codeql}`);
125+
process.exit(1);
126+
}
127+
}
109128
if (args.codeql === "built" || args.codeql === "build") {
110129
codeql = path.join(
111-
semmle_code!,
130+
vars.semmle_code!,
112131
"target",
113132
"intree",
114133
`codeql-${language}`,
115134
"codeql",
116135
);
117-
if (!fs.existsSync(codeql)) {
118-
console.error(`CodeQL executable not found: ${codeql}`);
119-
return 1;
120-
}
136+
check_codeql();
121137
} else if (args.codeql === "host") {
122138
codeql = "codeql";
123139
} else {
124140
codeql = args.codeql;
125-
if (fs.lstatSync(codeql).isDirectory()) {
126-
codeql = path.join(codeql, "codeql");
127-
if (process.platform === "win32") {
128-
codeql += ".exe";
129-
}
130-
}
131-
if (!fs.existsSync(codeql)) {
132-
console.error(`CodeQL executable not found: ${codeql}`);
133-
return 1;
141+
check_codeql();
142+
}
143+
if (fs.lstatSync(codeql).isDirectory()) {
144+
codeql = path.join(codeql, "codeql");
145+
if (process.platform === "win32") {
146+
codeql += ".exe";
134147
}
148+
check_codeql();
135149
}
136150

137151
return invoke([codeql, "test", "run", ...args.flags, "--", ...args.tests], {

misc/just/forward-command.ts

Lines changed: 35 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
import * as child_process from "child_process";
22
import * as path from "path";
3+
import * as fs from "fs";
34

4-
const just = process.env["JUST_EXECUTABLE"]!;
5+
const vars = {
6+
just: process.env["JUST_EXECUTABLE"] || "just",
7+
error: process.env["JUST_ERROR"] || "",
8+
};
59

610
console.debug = (...args: any[]) => {} // comment out to debug script
11+
const old_console_error = console.error;
12+
console.error = (message: string) => {
13+
old_console_error(vars.error + message);
14+
};
15+
716

817
function checkJustCommand(justfile: string, command: string, postitionalArgs: string[]): boolean {
18+
if (!fs.existsSync(justfile)) {
19+
return false;
20+
}
921
let {cwd, args} = getJustContext(justfile, command, [], postitionalArgs);
1022
console.debug(`Checking: ${cwd ? `cd ${cwd}; ` : ""}just ${args.join(", ")}`);
11-
const res = child_process.spawnSync(just, ["--dry-run", ...args], {
23+
const res = child_process.spawnSync(vars.just, ["--dry-run", ...args], {
1224
stdio: ["ignore", "ignore", "pipe"],
1325
encoding: "utf8",
1426
cwd,
@@ -18,24 +30,10 @@ function checkJustCommand(justfile: string, command: string, postitionalArgs: st
1830
return res.status === 0 && !res.stderr.includes(`forward-command.ts" ${command} "$@"`);
1931
}
2032

21-
function commonPath(paths: string[]): string {
22-
if (paths.length === 0) return "";
23-
if (paths.length === 1) return paths[0];
24-
const splitPaths = paths.map((p) => p.split(path.sep));
25-
let i;
26-
for (i = 0; i <= splitPaths[0].length; i++) {
27-
if (!splitPaths.every((parts) => parts[i] === splitPaths[0][i])) {
28-
break;
29-
}
30-
}
31-
return splitPaths[0].slice(0, i).join(path.sep);
32-
}
33-
34-
function findJustfile(command: string, paths: string[]): string | undefined {
35-
const common = commonPath(paths);
36-
for (let p = common;; p = path.dirname(p)) {
33+
function findJustfile(command: string, arg: string): string | undefined {
34+
for (let p = arg;; p = path.dirname(p)) {
3735
const candidate = path.join(p, "justfile");
38-
if (checkJustCommand(candidate, command, paths)) {
36+
if (checkJustCommand(candidate, command, [arg])) {
3937
return candidate;
4038
}
4139
if (p === "/" || p === ".") {
@@ -59,29 +57,26 @@ function forward(cmd: string, args: string[]): number {
5957
const positionalArgs = args.filter(
6058
(arg) => !is_non_positional.test(arg),
6159
);
62-
63-
const justfile = findJustfile(cmd, positionalArgs.length !== 0 ? positionalArgs : ["."]);
64-
if (!justfile) {
65-
if (positionalArgs.length <= 1) {
66-
console.error(`No justfile found for ${cmd}${positionalArgs.length === 0 ? "" : " on " + positionalArgs[0]}`);
60+
let justfiles: Map<string, string[]> = new Map();
61+
for(const arg of positionalArgs.length > 0 ? positionalArgs : ["."]) {
62+
const justfile = findJustfile(cmd, arg);
63+
if (!justfile) {
64+
console.error(`No justfile found for ${cmd} on ${arg}`);
6765
return 1;
6866
}
69-
console.log(`no common justfile recipe found for ${cmd} for all arguments, trying one argument at a time`);
70-
const runs: [string, string | undefined][] = positionalArgs.map(arg => [arg, findJustfile(cmd, [arg])]);
71-
for (const [arg, justfile] of runs) {
72-
if (!justfile) {
73-
console.error(`No justfile found for ${cmd} on ${arg}`);
74-
return 1;
75-
}
76-
}
77-
for (const [arg, justfile] of runs) {
78-
if (invokeJust(justfile!, cmd, flags, [arg]) !== 0) {
79-
return 1;
80-
}
67+
justfiles.set(justfile, [...justfiles.get(justfile) || [], arg]);
68+
}
69+
const invocations = Array.from(justfiles.entries()).map(([justfile, positionalArgs]) => {
70+
const {cwd, args} = getJustContext(justfile, cmd, flags, positionalArgs);
71+
console.log(`-> ${cwd ? `cd ${cwd}; ` : ""}just ${args.join(" ")}`);
72+
return { cwd, args };
73+
});
74+
for (const { cwd, args } of invocations) {
75+
if (invokeJust(cwd, args) !== 0) {
76+
return 1;
8177
}
82-
return 0;
8378
}
84-
return invokeJust(justfile, cmd, flags, positionalArgs);
79+
return 0;
8580
}
8681

8782
function getJustContext(justfile: string, cmd: string, flags: string[], positionalArgs: string[]): {args: string[], cwd?: string} {
@@ -109,11 +104,9 @@ function getJustContext(justfile: string, cmd: string, flags: string[], position
109104
}
110105
}
111106

112-
function invokeJust(justfile: string, cmd: string, flags: string[], positionalArgs: string[]): number {
113-
const { cwd, args } = getJustContext(justfile, cmd, flags, positionalArgs);
114-
console.log(`-> ${cwd ? `cd ${cwd}; ` : ""}just ${args.join(" ")}`);
107+
function invokeJust(cwd: string | undefined, args: string[]): number {
115108
try {
116-
child_process.execFileSync(just, args, {
109+
child_process.execFileSync(vars.just, args, {
117110
stdio: "inherit",
118111
cwd,
119112
});

misc/just/lib.just

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ error := style("error") + "error" + NORMAL + ": "
1010
cmd_sep := "\n#--------------------------------------------------------\n"
1111
export CMD_BEGIN := style("command") + cmd_sep
1212
export CMD_END := cmd_sep + NORMAL
13+
export JUST_ERROR := error
1314

1415
tsx := "npx tsx@4.19.0"
1516

0 commit comments

Comments
 (0)