Allow runTool to inherit env

This commit is contained in:
Michael B. Gale
2026-10-23 13:09:20 +01:00
parent 7cd2203aed
commit 6d448e0c5f
4 changed files with 76 additions and 32 deletions

52
lib/entry-points.js generated
View File

@@ -166124,6 +166124,17 @@ var ReadOnlyEnv = class {
get() {
return { ...this.vars };
}
/** Gets a copy of the underlying environment, where the values are not `undefined`. */
getDefined() {
const result = {};
for (const [key, val] of Object.entries(this.vars)) {
if (val === void 0) {
continue;
}
result[key] = val;
}
return result;
}
/** Tries to get the value for `name` and throws if there isn't one. */
getRequired(name) {
return getRequiredEnvVar(this.vars, name);
@@ -170350,7 +170361,7 @@ function ensureEndsInPeriod(text) {
return text[text.length - 1] === "." ? text : `${text}.`;
}
var MAX_STDERR_BUFFER_SIZE = 2e4;
async function runTool(cmd, args = [], opts = {}) {
async function runTool(env, cmd, args = [], opts = {}) {
let stdout = "";
let stderr = "";
if (!opts.noStreamStdout) {
@@ -170358,6 +170369,7 @@ async function runTool(cmd, args = [], opts = {}) {
`);
}
const exitCode = await new toolrunner.ToolRunner(cmd, args, {
env: env.getDefined(),
ignoreReturnCode: true,
listeners: {
stdout: (data) => {
@@ -177026,6 +177038,7 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion, env = getEnv()) {
);
if (result === void 0) {
result = await runCliJson(
env,
cmd,
["version", "--format=json"],
{
@@ -177096,6 +177109,7 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion, env = getEnv()) {
"--sublanguage-file-coverage"
] : ["--no-calculate-baseline"];
await runCli(
env,
cmd,
[
"database",
@@ -177140,10 +177154,10 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion, env = getEnv()) {
env.getOptional("CODEQL_VERBOSITY" /* CLI_VERBOSITY */) ?? EXTRACTION_DEBUG_MODE_VERBOSITY
);
}
await runCli(autobuildCmd);
await runCli(env, autobuildCmd);
},
async extractScannedLanguage(config, language) {
await runCli(cmd, [
await runCli(env, cmd, [
"database",
"trace-command",
"--index-traceless-dbs",
@@ -177158,7 +177172,7 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion, env = getEnv()) {
applyAutobuildAzurePipelinesTimeoutFix(env);
}
try {
await runCli(cmd, [
await runCli(env, cmd, [
"database",
"trace-command",
"--use-build-mode",
@@ -177189,12 +177203,12 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion, env = getEnv()) {
...getExtraOptionsFromEnv(["database", "finalize"]),
databasePath
];
await runCli(cmd, args);
await runCli(env, cmd, args);
},
async resolveLanguages({
filterToLanguagesWithQueries
} = { filterToLanguagesWithQueries: false }) {
return runCliJson(cmd, [
return runCliJson(env, cmd, [
"resolve",
"languages",
"--format=betterjson",
@@ -177218,7 +177232,11 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion, env = getEnv()) {
if (workingDir !== void 0) {
codeqlArgs.push("--working-dir", workingDir);
}
return await runCliJson(cmd, codeqlArgs);
return await runCliJson(
env,
cmd,
codeqlArgs
);
},
async databaseRunQueries(databasePath, flags, queries = []) {
const codeqlArgs = [
@@ -177234,7 +177252,7 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion, env = getEnv()) {
ignoringOptions: ["--expect-discarded-cache"]
})
];
await runCli(cmd, codeqlArgs);
await runCli(env, cmd, codeqlArgs);
},
async databaseInterpretResults(databasePath, querySuitePaths, sarifFile, threadsFlag, verbosityFlag, sarifRunPropertyFlag, automationDetailsId, config, features) {
const shouldExportDiagnostics = await features.getValue(
@@ -177275,7 +177293,7 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion, env = getEnv()) {
if (querySuitePaths) {
codeqlArgs.push(...querySuitePaths);
}
return await runCli(cmd, codeqlArgs, {
return await runCli(env, cmd, codeqlArgs, {
noStreamStdout: true
});
},
@@ -177289,7 +177307,7 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion, env = getEnv()) {
`--cache-cleanup=${cleanupLevel}`,
...getExtraOptionsFromEnv(["database", "cleanup"])
];
await runCli(cmd, codeqlArgs);
await runCli(env, cmd, codeqlArgs);
}
},
async databaseBundle(databasePath, outputFilePath, databaseName, includeDiagnostics, alsoIncludeRelativePaths) {
@@ -177403,7 +177421,7 @@ Output was: ${extractorPath}`
...getExtraOptionsFromEnv(["resolve", "queries"]),
...queries
];
return await runCliJson(cmd, codeqlArgs, {
return await runCliJson(env, cmd, codeqlArgs, {
noStreamStdout: true
});
},
@@ -177415,7 +177433,7 @@ Output was: ${extractorPath}`
"--format=json",
...getExtraOptionsFromEnv(["resolve", "database"])
];
return await runCliJson(cmd, codeqlArgs, {
return await runCliJson(env, cmd, codeqlArgs, {
noStreamStdout: true
});
},
@@ -177435,7 +177453,7 @@ Output was: ${extractorPath}`
if (mergeRunsFromEqualCategory) {
args.push("--sarif-merge-runs-from-equal-category");
}
await runCli(cmd, args);
await runCli(env, cmd, args);
}
};
if (checkVersion && !await codeQlVersionAtLeast(codeql, CODEQL_MINIMUM_VERSION)) {
@@ -177489,9 +177507,9 @@ function getExtraOptions(options, paths, pathInfo) {
);
return all.concat(specific);
}
async function runCli(cmd, args = [], opts = {}) {
async function runCli(env, cmd, args = [], opts = {}) {
try {
return await runTool(cmd, args, opts);
return await runTool(env, cmd, args, opts);
} catch (e) {
if (e instanceof CommandInvocationError) {
throw wrapCliConfigurationError(new CliError(e));
@@ -177499,8 +177517,8 @@ async function runCli(cmd, args = [], opts = {}) {
throw e;
}
}
async function runCliJson(cmd, args = [], opts = {}) {
const output = await runCli(cmd, args, opts);
async function runCliJson(env, cmd, args = [], opts = {}) {
const output = await runCli(env, cmd, args, opts);
try {
return JSON.parse(output);
} catch (e) {

View File

@@ -361,9 +361,10 @@ const MAX_STDERR_BUFFER_SIZE = 20000;
* Runs a CLI tool.
*
* @returns Standard output produced by the tool.
* @throws A `CommandInvocationError` if the tool exits with a non-zero status code.
* @throws A {@link CommandInvocationError} if the tool exits with a non-zero status code.
*/
export async function runTool(
env: Env,
cmd: string,
args: string[] = [],
opts: { stdin?: string; noStreamStdout?: boolean } = {},
@@ -374,6 +375,7 @@ export async function runTool(
process.stdout.write(`[command]${cmd} ${args.join(" ")}\n`);
}
const exitCode = await new toolrunner.ToolRunner(cmd, args, {
env: env.getDefined(),
ignoreReturnCode: true,
listeners: {
stdout: (data: Buffer) => {

View File

@@ -514,6 +514,7 @@ export async function getCodeQLForCmd(
);
if (result === undefined) {
result = await runCliJson<VersionInfo>(
env,
cmd,
["version", "--format=json"],
{
@@ -597,6 +598,7 @@ export async function getCodeQLForCmd(
: ["--no-calculate-baseline"];
await runCli(
env,
cmd,
[
"database",
@@ -663,10 +665,10 @@ export async function getCodeQLForCmd(
// When `DYLD_INSERT_LIBRARIES` is set in the environment for a step,
// the Actions runtime introduces its own workaround for SIP
// (https://github.com/actions/runner/pull/416).
await runCli(autobuildCmd);
await runCli(env, autobuildCmd);
},
async extractScannedLanguage(config: Config, language: Language) {
await runCli(cmd, [
await runCli(env, cmd, [
"database",
"trace-command",
"--index-traceless-dbs",
@@ -681,7 +683,7 @@ export async function getCodeQLForCmd(
applyAutobuildAzurePipelinesTimeoutFix(env);
}
try {
await runCli(cmd, [
await runCli(env, cmd, [
"database",
"trace-command",
"--use-build-mode",
@@ -720,7 +722,7 @@ export async function getCodeQLForCmd(
...getExtraOptionsFromEnv(["database", "finalize"]),
databasePath,
];
await runCli(cmd, args);
await runCli(env, cmd, args);
},
async resolveLanguages(
{
@@ -729,7 +731,7 @@ export async function getCodeQLForCmd(
filterToLanguagesWithQueries: boolean;
} = { filterToLanguagesWithQueries: false },
) {
return runCliJson<ResolveLanguagesOutput>(cmd, [
return runCliJson<ResolveLanguagesOutput>(env, cmd, [
"resolve",
"languages",
"--format=betterjson",
@@ -758,7 +760,11 @@ export async function getCodeQLForCmd(
if (workingDir !== undefined) {
codeqlArgs.push("--working-dir", workingDir);
}
return await runCliJson<ResolveBuildEnvironmentOutput>(cmd, codeqlArgs);
return await runCliJson<ResolveBuildEnvironmentOutput>(
env,
cmd,
codeqlArgs,
);
},
async databaseRunQueries(
databasePath: string,
@@ -777,7 +783,7 @@ export async function getCodeQLForCmd(
ignoringOptions: ["--expect-discarded-cache"],
}),
];
await runCli(cmd, codeqlArgs);
await runCli(env, cmd, codeqlArgs);
},
async databaseInterpretResults(
databasePath: string,
@@ -830,7 +836,7 @@ export async function getCodeQLForCmd(
}
// Capture the stdout, which contains the analysis summary. Don't stream it to the Actions
// logs to avoid printing it twice.
return await runCli(cmd, codeqlArgs, {
return await runCli(env, cmd, codeqlArgs, {
noStreamStdout: true,
});
},
@@ -847,7 +853,7 @@ export async function getCodeQLForCmd(
`--cache-cleanup=${cleanupLevel}`,
...getExtraOptionsFromEnv(["database", "cleanup"]),
];
await runCli(cmd, codeqlArgs);
await runCli(env, cmd, codeqlArgs);
}
},
async databaseBundle(
@@ -995,7 +1001,7 @@ export async function getCodeQLForCmd(
...getExtraOptionsFromEnv(["resolve", "queries"]),
...queries,
];
return await runCliJson<string[]>(cmd, codeqlArgs, {
return await runCliJson<string[]>(env, cmd, codeqlArgs, {
noStreamStdout: true,
});
},
@@ -1009,7 +1015,7 @@ export async function getCodeQLForCmd(
"--format=json",
...getExtraOptionsFromEnv(["resolve", "database"]),
];
return await runCliJson<ResolveDatabaseOutput>(cmd, codeqlArgs, {
return await runCliJson<ResolveDatabaseOutput>(env, cmd, codeqlArgs, {
noStreamStdout: true,
});
},
@@ -1036,7 +1042,7 @@ export async function getCodeQLForCmd(
args.push("--sarif-merge-runs-from-equal-category");
}
await runCli(cmd, args);
await runCli(env, cmd, args);
},
};
// To ensure that status reports include the CodeQL CLI version wherever
@@ -1153,12 +1159,13 @@ export function getExtraOptions(
}
async function runCli(
env: Env,
cmd: string,
args: string[] = [],
opts: { stdin?: string; noStreamStdout?: boolean } = {},
): Promise<string> {
try {
return await runTool(cmd, args, opts);
return await runTool(env, cmd, args, opts);
} catch (e) {
if (e instanceof CommandInvocationError) {
throw wrapCliConfigurationError(new CliError(e));
@@ -1169,6 +1176,8 @@ async function runCli(
/**
* Wraps the command executor {@link runCli} and tries to parse the output as JSON.
*
* @param env The environment variables.
* @param cmd The command to run.
* @param args The arguments to pass to the command.
* @param opts The options for running the command.
@@ -1177,11 +1186,12 @@ async function runCli(
* @returns The parsed JSON output from the command.
*/
async function runCliJson<T>(
env: Env,
cmd: string,
args: string[] = [],
opts: { stdin?: string; noStreamStdout?: boolean } = {},
): Promise<T> {
const output = await runCli(cmd, args, opts);
const output = await runCli(env, cmd, args, opts);
try {
return JSON.parse(output) as T;
} catch (e) {

View File

@@ -306,6 +306,20 @@ export class ReadOnlyEnv {
return { ...this.vars };
}
/** Gets a copy of the underlying environment, where the values are not `undefined`. */
public getDefined(): Record<string, string> {
const result: Record<string, string> = {};
for (const [key, val] of Object.entries(this.vars)) {
if (val === undefined) {
continue;
}
result[key] = val;
}
return result;
}
/** Tries to get the value for `name` and throws if there isn't one. */
public getRequired(name: string): string {
return getRequiredEnvVar(this.vars, name);