11import * as child_process from "child_process";
22import * as path from "path";
33import * as os from "os";
4+ import * as fs from "fs";
45
56function invoke(
67 invocation: string[],
@@ -28,65 +29,68 @@ type Args = {
2829 tests: string[];
2930 flags: string[];
3031 env: string[];
31- build: boolean ;
32- testing_level: number ;
32+ codeql: string ;
33+ all: boolean ;
3334};
3435
3536function parseArgs(args: Args, argv: string) {
36- argv.split(/(?<!\\) /).forEach((arg) => {
37- if (arg === "--no-build") {
38- args.build = false;
39- } else if (arg.startsWith("-")) {
40- args.flags.push(arg);
41- } else if (/^[A-Z_][A-Z_0-9]*=.*$/.test(arg)) {
42- args.env.push(arg);
43- } else if (/^\++$/.test(arg)) {
44- args.testing_level = Math.max(args.testing_level, arg.length);
45- } else if (arg !== "") {
46- args.tests.push(arg);
47- }
48- });
37+ argv.split(/(?<!\\) /)
38+ .map((arg) => arg.replace("\\ ", " "))
39+ .forEach((arg) => {
40+ if (arg.startsWith("--codeql=")) {
41+ args.codeql = arg.split("=")[1];
42+ } else if (arg === "+" || arg === "--all-checks") {
43+ args.all = true;
44+ } else if (arg.startsWith("-")) {
45+ args.flags.push(arg);
46+ } else if (/^[A-Z_][A-Z_0-9]*=.*$/.test(arg)) {
47+ args.env.push(arg);
48+ } else if (arg !== "") {
49+ args.tests.push(arg);
50+ }
51+ });
4952}
5053
5154function codeqlTestRun(argv: string[]): number {
52- const [language, extra_args, ...plus] = argv;
53- let codeql = process.env["SEMMLE_CODE"]
54- ? path.join(
55- process.env["SEMMLE_CODE"],
56- "target",
57- "intree",
58- `codeql-${language}`,
59- "codeql",
60- )
61- : "codeql";
55+ const semmle_code = process.env["SEMMLE_CODE"];
56+ const [language, base_args, all_args, extra_args] = argv;
6257 const ram_per_thread = process.platform === "linux" ? 3000 : 2048;
6358 const cpus = os.cpus().length;
6459 let args: Args = {
6560 tests: [],
6661 flags: [`--ram=${ram_per_thread * cpus}`, `-j${cpus}`],
6762 env: [],
68- build: true ,
69- testing_level: 0 ,
63+ codeql: semmle_code ? " build" : "host" ,
64+ all: false ,
7065 };
66+ parseArgs(args, base_args);
7167 parseArgs(args, extra_args);
72- for (let i = 0; i < Math.min(plus.length, args.testing_level); i++) {
73- parseArgs(args, plus[i]);
68+ if (args.all) {
69+ parseArgs(args, all_args);
70+ }
71+ if (!semmle_code && (args.codeql === "build" || args.codeql === "built")) {
72+ console.error(
73+ "Using `--codeql=build` or `--codeql=built` requires working with the internal repository",
74+ );
75+ return 1;
7476 }
7577 if (args.tests.length === 0) {
7678 args.tests.push(".");
7779 }
78- if (args.build && process.env["SEMMLE_CODE"]) {
79- // If SEMMLE_CODE is set, we are in the semmle-code repo, so we build the codeql binary.
80- // Otherwise, we use codeql from PATH.
80+ if (args.codeql === "build") {
8181 if (
8282 invoke(["python3", "build", `target/intree/codeql-${language}`], {
83- cwd: process.env["SEMMLE_CODE"] ,
83+ cwd: semmle_code ,
8484 }) !== 0
8585 ) {
8686 return 1;
8787 }
8888 }
89- process.env["CODEQL_CONFIG_FILE"] ||= "."; // disable the default implicit config file, but keep an explicit one
89+ if (args.codeql !== "host") {
90+ // disable the default implicit config file, but keep an explicit one
91+ // this is the same behavior wrt to `--codeql` as the integration test runner
92+ process.env["CODEQL_CONFIG_FILE"] ||= ".";
93+ }
9094 // Set and unset environment variables
9195 args.env.forEach((envVar) => {
9296 const [key, value] = envVar.split("=", 2);
@@ -101,6 +105,31 @@ function codeqlTestRun(argv: string[]): number {
101105 process.exit(1);
102106 }
103107 });
108+ let codeql;
109+ if (args.codeql === "built" || args.codeql === "build") {
110+ codeql = path.join(
111+ semmle_code!,
112+ "target",
113+ "intree",
114+ `codeql-${language}`,
115+ "codeql",
116+ );
117+ } else if (args.codeql === "host") {
118+ codeql = "codeql";
119+ } else {
120+ codeql = args.codeql;
121+ if (fs.lstatSync(codeql).isDirectory()) {
122+ codeql = path.join(codeql, "codeql");
123+ if (process.platform === "win32") {
124+ codeql += ".exe";
125+ }
126+ }
127+ if (!fs.existsSync(codeql)) {
128+ console.error(`CodeQL executable not found: ${codeql}`);
129+ return 1;
130+ }
131+ }
132+
104133 return invoke([codeql, "test", "run", ...args.flags, "--", ...args.tests], {
105134 log_prefix: args.env.join(" "),
106135 });
0 commit comments