Replace analyze with run-queries and interpret-results
This commit is contained in:
parent
c09500540c
commit
2cc885d66e
9 changed files with 180 additions and 160 deletions
63
lib/analyze.js
generated
63
lib/analyze.js
generated
|
|
@ -15,7 +15,6 @@ const codeql_1 = require("./codeql");
|
|||
const count_loc_1 = require("./count-loc");
|
||||
const languages_1 = require("./languages");
|
||||
const sharedEnv = __importStar(require("./shared-environment"));
|
||||
const upload_lib_1 = require("./upload-lib");
|
||||
const util = __importStar(require("./util"));
|
||||
class CodeQLAnalysisError extends Error {
|
||||
constructor(queriesStatusReport, message) {
|
||||
|
|
@ -85,59 +84,43 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
|
|||
// that here.
|
||||
config.paths, config.pathsIgnore, config.languages, logger);
|
||||
for (const language of config.languages) {
|
||||
logger.startGroup(`Analyzing ${language}`);
|
||||
logger.startGroup(`Running queries for ${language}`);
|
||||
const queries = config.queries[language];
|
||||
if (queries === undefined ||
|
||||
(queries.builtin.length === 0 && queries.custom.length === 0)) {
|
||||
throw new Error(`Unable to analyse ${language} as no queries were selected for this language`);
|
||||
}
|
||||
try {
|
||||
let analysisSummaryBuiltIn = "";
|
||||
const customAnalysisSummaries = [];
|
||||
const querySuitePaths = [];
|
||||
if (queries["builtin"].length > 0) {
|
||||
const startTimeBuiltIn = new Date().getTime();
|
||||
const { sarifFile, stdout } = await runQueryGroup(language, "builtin", queries["builtin"], sarifFolder, undefined);
|
||||
analysisSummaryBuiltIn = stdout;
|
||||
await injectLinesOfCode(sarifFile, language, locPromise);
|
||||
querySuitePaths.push(await runQueryGroup(language, "builtin", queries["builtin"], undefined));
|
||||
statusReport[`analyze_builtin_queries_${language}_duration_ms`] =
|
||||
new Date().getTime() - startTimeBuiltIn;
|
||||
}
|
||||
const startTimeCustom = new Date().getTime();
|
||||
const temporarySarifDir = config.tempDir;
|
||||
const temporarySarifFiles = [];
|
||||
let ranCustom = false;
|
||||
for (let i = 0; i < queries["custom"].length; ++i) {
|
||||
if (queries["custom"][i].queries.length > 0) {
|
||||
const { sarifFile, stdout } = await runQueryGroup(language, `custom-${i}`, queries["custom"][i].queries, temporarySarifDir, queries["custom"][i].searchPath);
|
||||
customAnalysisSummaries.push(stdout);
|
||||
temporarySarifFiles.push(sarifFile);
|
||||
querySuitePaths.push(await runQueryGroup(language, `custom-${i}`, queries["custom"][i].queries, queries["custom"][i].searchPath));
|
||||
ranCustom = true;
|
||||
}
|
||||
}
|
||||
if (temporarySarifFiles.length > 0) {
|
||||
const sarifFile = path.join(sarifFolder, `${language}-custom.sarif`);
|
||||
fs.writeFileSync(sarifFile, upload_lib_1.combineSarifFiles(temporarySarifFiles));
|
||||
await injectLinesOfCode(sarifFile, language, locPromise);
|
||||
if (ranCustom) {
|
||||
statusReport[`analyze_custom_queries_${language}_duration_ms`] =
|
||||
new Date().getTime() - startTimeCustom;
|
||||
}
|
||||
logger.endGroup();
|
||||
// Print the LoC baseline and the summary results from database analyze for the standard
|
||||
// query suite and (if appropriate) each custom query suite.
|
||||
logger.startGroup(`Analysis summary for ${language}`);
|
||||
printLinesOfCodeSummary(logger, language, await locPromise);
|
||||
logger.info(analysisSummaryBuiltIn);
|
||||
for (const [i, customSummary] of customAnalysisSummaries.entries()) {
|
||||
if (customSummary.trim() === "") {
|
||||
continue;
|
||||
}
|
||||
const description = customAnalysisSummaries.length === 1
|
||||
? "custom queries"
|
||||
: `custom query suite ${i + 1}/${customAnalysisSummaries.length}`;
|
||||
logger.info(`Analysis summary for ${description}:`);
|
||||
logger.info("");
|
||||
logger.info(customSummary);
|
||||
logger.info("");
|
||||
}
|
||||
logger.startGroup(`Interpreting results for ${language}`);
|
||||
const startTimeInterpretResults = new Date().getTime();
|
||||
const sarifFile = path.join(sarifFolder, `${language}.sarif`);
|
||||
const analysisSummary = await runInterpretResults(language, querySuitePaths, sarifFile);
|
||||
await injectLinesOfCode(sarifFile, language, locPromise);
|
||||
statusReport[`interpret_results_${language}_duration_ms`] =
|
||||
new Date().getTime() - startTimeInterpretResults;
|
||||
logger.endGroup();
|
||||
logger.info(analysisSummary);
|
||||
printLinesOfCodeSummary(logger, language, await locPromise);
|
||||
}
|
||||
catch (e) {
|
||||
logger.info(e);
|
||||
|
|
@ -146,7 +129,12 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
|
|||
}
|
||||
}
|
||||
return statusReport;
|
||||
async function runQueryGroup(language, type, queries, destinationFolder, searchPath) {
|
||||
async function runInterpretResults(language, queries, sarifFile) {
|
||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
|
||||
return await codeql.databaseInterpretResults(databasePath, queries, sarifFile, addSnippetsFlag, threadsFlag, automationDetailsId);
|
||||
}
|
||||
async function runQueryGroup(language, type, queries, searchPath) {
|
||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||
// Pass the queries to codeql using a file instead of using the command
|
||||
// line to avoid command line length restrictions, particularly on windows.
|
||||
|
|
@ -156,11 +144,10 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
|
|||
.join("\n");
|
||||
fs.writeFileSync(querySuitePath, querySuiteContents);
|
||||
logger.debug(`Query suite file for ${language}...\n${querySuiteContents}`);
|
||||
const sarifFile = path.join(destinationFolder, `${language}-${type}.sarif`);
|
||||
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
|
||||
const databaseAnalyzeStdout = await codeql.databaseAnalyze(databasePath, sarifFile, searchPath, querySuitePath, memoryFlag, addSnippetsFlag, threadsFlag, automationDetailsId);
|
||||
logger.debug(`SARIF results for database ${language} created at "${sarifFile}"`);
|
||||
return { sarifFile, stdout: databaseAnalyzeStdout };
|
||||
await codeql.databaseRunQueries(databasePath, searchPath, querySuitePath, memoryFlag, threadsFlag);
|
||||
logger.debug(`BQRS results produced for ${language} (queries: ${type})"`);
|
||||
return querySuitePath;
|
||||
}
|
||||
}
|
||||
exports.runQueries = runQueries;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
15
lib/analyze.test.js
generated
15
lib/analyze.test.js
generated
|
|
@ -41,7 +41,10 @@ ava_1.default("status report fields and search path setting", async (t) => {
|
|||
const threadsFlag = "";
|
||||
for (const language of Object.values(languages_1.Language)) {
|
||||
codeql_1.setCodeQL({
|
||||
databaseAnalyze: async (_, sarifFile, searchPath) => {
|
||||
databaseRunQueries: async (_db, searchPath) => {
|
||||
searchPathsUsed.push(searchPath);
|
||||
},
|
||||
databaseInterpretResults: async (_db, _queriesRun, sarifFile) => {
|
||||
fs.writeFileSync(sarifFile, JSON.stringify({
|
||||
runs: [
|
||||
// variant 1 uses ruleId
|
||||
|
|
@ -71,7 +74,6 @@ ava_1.default("status report fields and search path setting", async (t) => {
|
|||
{},
|
||||
],
|
||||
}));
|
||||
searchPathsUsed.push(searchPath);
|
||||
return "";
|
||||
},
|
||||
});
|
||||
|
|
@ -98,8 +100,9 @@ ava_1.default("status report fields and search path setting", async (t) => {
|
|||
custom: [],
|
||||
};
|
||||
const builtinStatusReport = await analyze_1.runQueries(tmpDir, memoryFlag, addSnippetsFlag, threadsFlag, undefined, config, logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(Object.keys(builtinStatusReport).length, 1);
|
||||
t.deepEqual(Object.keys(builtinStatusReport).length, 2);
|
||||
t.true(`analyze_builtin_queries_${language}_duration_ms` in builtinStatusReport);
|
||||
t.true(`interpret_results_${language}_duration_ms` in builtinStatusReport);
|
||||
config.queries[language] = {
|
||||
builtin: [],
|
||||
custom: [
|
||||
|
|
@ -114,8 +117,9 @@ ava_1.default("status report fields and search path setting", async (t) => {
|
|||
],
|
||||
};
|
||||
const customStatusReport = await analyze_1.runQueries(tmpDir, memoryFlag, addSnippetsFlag, threadsFlag, undefined, config, logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(Object.keys(customStatusReport).length, 1);
|
||||
t.deepEqual(Object.keys(customStatusReport).length, 2);
|
||||
t.true(`analyze_custom_queries_${language}_duration_ms` in customStatusReport);
|
||||
t.true(`interpret_results_${language}_duration_ms` in customStatusReport);
|
||||
t.deepEqual(searchPathsUsed, [undefined, "/1", "/2"]);
|
||||
}
|
||||
verifyLineCounts(tmpDir);
|
||||
|
|
@ -123,8 +127,7 @@ ava_1.default("status report fields and search path setting", async (t) => {
|
|||
function verifyLineCounts(tmpDir) {
|
||||
// eslint-disable-next-line github/array-foreach
|
||||
Object.keys(languages_1.Language).forEach((lang, i) => {
|
||||
verifyLineCountForFile(lang, path.join(tmpDir, `${lang}-builtin.sarif`), i + 1);
|
||||
verifyLineCountForFile(lang, path.join(tmpDir, `${lang}-custom.sarif`), i + 1);
|
||||
verifyLineCountForFile(lang, path.join(tmpDir, `${lang}.sarif`), i + 1);
|
||||
});
|
||||
}
|
||||
function verifyLineCountForFile(lang, filePath, lineCount) {
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"analyze.test.js","sourceRoot":"","sources":["../src/analyze.test.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"analyze.test.js","sourceRoot":"","sources":["../src/analyze.test.ts"],"names":[],"mappings":"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"}
|
||||
34
lib/codeql.js
generated
34
lib/codeql.js
generated
|
|
@ -285,8 +285,9 @@ function setCodeQL(partialCodeql) {
|
|||
finalizeDatabase: resolveFunction(partialCodeql, "finalizeDatabase"),
|
||||
resolveLanguages: resolveFunction(partialCodeql, "resolveLanguages"),
|
||||
resolveQueries: resolveFunction(partialCodeql, "resolveQueries"),
|
||||
databaseAnalyze: resolveFunction(partialCodeql, "databaseAnalyze"),
|
||||
databaseCleanup: resolveFunction(partialCodeql, "databaseCleanup"),
|
||||
databaseRunQueries: resolveFunction(partialCodeql, "databaseRunQueries"),
|
||||
databaseInterpretResults: resolveFunction(partialCodeql, "databaseInterpretResults"),
|
||||
};
|
||||
return cachedCodeQL;
|
||||
}
|
||||
|
|
@ -464,31 +465,40 @@ function getCodeQLForCmd(cmd) {
|
|||
throw new Error(`Unexpected output from codeql resolve queries: ${e}`);
|
||||
}
|
||||
},
|
||||
async databaseAnalyze(databasePath, sarifFile, extraSearchPath, querySuite, memoryFlag, addSnippetsFlag, threadsFlag, automationDetailsId) {
|
||||
async databaseRunQueries(databasePath, extraSearchPath, querySuitePath, memoryFlag, threadsFlag) {
|
||||
const args = [
|
||||
"database",
|
||||
"analyze",
|
||||
"run-queries",
|
||||
memoryFlag,
|
||||
threadsFlag,
|
||||
databasePath,
|
||||
"--min-disk-free=1024",
|
||||
"--format=sarif-latest",
|
||||
"--sarif-multicause-markdown",
|
||||
"--sarif-group-rules-by-pack",
|
||||
`--output=${sarifFile}`,
|
||||
addSnippetsFlag,
|
||||
// Enable progress verbosity so we log each query as it's interpreted. This aids debugging
|
||||
// when interpretation takes a while for one of the queries being analyzed.
|
||||
"-v",
|
||||
...getExtraOptionsFromEnv(["database", "analyze"]),
|
||||
...getExtraOptionsFromEnv(["database", "run-queries"]),
|
||||
];
|
||||
if (extraSearchPath !== undefined) {
|
||||
args.push("--additional-packs", extraSearchPath);
|
||||
}
|
||||
args.push(querySuitePath);
|
||||
await new toolrunner.ToolRunner(cmd, args).exec();
|
||||
},
|
||||
async databaseInterpretResults(databasePath, querySuitePaths, sarifFile, addSnippetsFlag, threadsFlag, automationDetailsId) {
|
||||
const args = [
|
||||
"database",
|
||||
"interpret-results",
|
||||
threadsFlag,
|
||||
"--format=sarif-latest",
|
||||
"--print-metrics-summary",
|
||||
"--sarif-group-rules-by-pack",
|
||||
"-v",
|
||||
`--output=${sarifFile}`,
|
||||
addSnippetsFlag,
|
||||
...getExtraOptionsFromEnv(["database", "interpret-results"]),
|
||||
];
|
||||
if (automationDetailsId !== undefined) {
|
||||
args.push("--sarif-category", automationDetailsId);
|
||||
}
|
||||
args.push(querySuite);
|
||||
args.push(databasePath, ...querySuitePaths);
|
||||
// capture stdout, which contains analysis summaries
|
||||
let output = "";
|
||||
await new toolrunner.ToolRunner(cmd, args, {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -26,7 +26,7 @@ test("status report fields and search path setting", async (t) => {
|
|||
return obj;
|
||||
}, {});
|
||||
sinon.stub(count, "countLoc").resolves(mockLinesOfCode);
|
||||
let searchPathsUsed: string[] = [];
|
||||
let searchPathsUsed: Array<string | undefined> = [];
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
|
||||
|
|
@ -36,10 +36,16 @@ test("status report fields and search path setting", async (t) => {
|
|||
|
||||
for (const language of Object.values(Language)) {
|
||||
setCodeQL({
|
||||
databaseAnalyze: async (
|
||||
_,
|
||||
sarifFile: string,
|
||||
databaseRunQueries: async (
|
||||
_db: string,
|
||||
searchPath: string | undefined
|
||||
) => {
|
||||
searchPathsUsed.push(searchPath);
|
||||
},
|
||||
databaseInterpretResults: async (
|
||||
_db: string,
|
||||
_queriesRun: string[],
|
||||
sarifFile: string
|
||||
) => {
|
||||
fs.writeFileSync(
|
||||
sarifFile,
|
||||
|
|
@ -75,7 +81,6 @@ test("status report fields and search path setting", async (t) => {
|
|||
],
|
||||
})
|
||||
);
|
||||
searchPathsUsed.push(searchPath!);
|
||||
return "";
|
||||
},
|
||||
});
|
||||
|
|
@ -112,10 +117,13 @@ test("status report fields and search path setting", async (t) => {
|
|||
config,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
t.deepEqual(Object.keys(builtinStatusReport).length, 1);
|
||||
t.deepEqual(Object.keys(builtinStatusReport).length, 2);
|
||||
t.true(
|
||||
`analyze_builtin_queries_${language}_duration_ms` in builtinStatusReport
|
||||
);
|
||||
t.true(
|
||||
`interpret_results_${language}_duration_ms` in builtinStatusReport
|
||||
);
|
||||
|
||||
config.queries[language] = {
|
||||
builtin: [],
|
||||
|
|
@ -139,10 +147,11 @@ test("status report fields and search path setting", async (t) => {
|
|||
config,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
t.deepEqual(Object.keys(customStatusReport).length, 1);
|
||||
t.deepEqual(Object.keys(customStatusReport).length, 2);
|
||||
t.true(
|
||||
`analyze_custom_queries_${language}_duration_ms` in customStatusReport
|
||||
);
|
||||
t.true(`interpret_results_${language}_duration_ms` in customStatusReport);
|
||||
t.deepEqual(searchPathsUsed, [undefined, "/1", "/2"]);
|
||||
}
|
||||
|
||||
|
|
@ -154,12 +163,7 @@ test("status report fields and search path setting", async (t) => {
|
|||
Object.keys(Language).forEach((lang, i) => {
|
||||
verifyLineCountForFile(
|
||||
lang as Language,
|
||||
path.join(tmpDir, `${lang}-builtin.sarif`),
|
||||
i + 1
|
||||
);
|
||||
verifyLineCountForFile(
|
||||
lang as Language,
|
||||
path.join(tmpDir, `${lang}-custom.sarif`),
|
||||
path.join(tmpDir, `${lang}.sarif`),
|
||||
i + 1
|
||||
);
|
||||
});
|
||||
|
|
|
|||
117
src/analyze.ts
117
src/analyze.ts
|
|
@ -10,7 +10,6 @@ import { countLoc, getIdPrefix } from "./count-loc";
|
|||
import { isScannedLanguage, Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import * as sharedEnv from "./shared-environment";
|
||||
import { combineSarifFiles } from "./upload-lib";
|
||||
import * as util from "./util";
|
||||
|
||||
export class CodeQLAnalysisError extends Error {
|
||||
|
|
@ -163,7 +162,7 @@ export async function runQueries(
|
|||
);
|
||||
|
||||
for (const language of config.languages) {
|
||||
logger.startGroup(`Analyzing ${language}`);
|
||||
logger.startGroup(`Running queries for ${language}`);
|
||||
|
||||
const queries = config.queries[language];
|
||||
if (
|
||||
|
|
@ -176,71 +175,54 @@ export async function runQueries(
|
|||
}
|
||||
|
||||
try {
|
||||
let analysisSummaryBuiltIn = "";
|
||||
const customAnalysisSummaries: string[] = [];
|
||||
const querySuitePaths: string[] = [];
|
||||
if (queries["builtin"].length > 0) {
|
||||
const startTimeBuiltIn = new Date().getTime();
|
||||
const { sarifFile, stdout } = await runQueryGroup(
|
||||
language,
|
||||
"builtin",
|
||||
queries["builtin"],
|
||||
sarifFolder,
|
||||
undefined
|
||||
querySuitePaths.push(
|
||||
await runQueryGroup(
|
||||
language,
|
||||
"builtin",
|
||||
queries["builtin"],
|
||||
undefined
|
||||
)
|
||||
);
|
||||
analysisSummaryBuiltIn = stdout;
|
||||
await injectLinesOfCode(sarifFile, language, locPromise);
|
||||
|
||||
statusReport[`analyze_builtin_queries_${language}_duration_ms`] =
|
||||
new Date().getTime() - startTimeBuiltIn;
|
||||
}
|
||||
const startTimeCustom = new Date().getTime();
|
||||
const temporarySarifDir = config.tempDir;
|
||||
const temporarySarifFiles: string[] = [];
|
||||
let ranCustom = false;
|
||||
for (let i = 0; i < queries["custom"].length; ++i) {
|
||||
if (queries["custom"][i].queries.length > 0) {
|
||||
const { sarifFile, stdout } = await runQueryGroup(
|
||||
language,
|
||||
`custom-${i}`,
|
||||
queries["custom"][i].queries,
|
||||
temporarySarifDir,
|
||||
queries["custom"][i].searchPath
|
||||
querySuitePaths.push(
|
||||
await runQueryGroup(
|
||||
language,
|
||||
`custom-${i}`,
|
||||
queries["custom"][i].queries,
|
||||
queries["custom"][i].searchPath
|
||||
)
|
||||
);
|
||||
customAnalysisSummaries.push(stdout);
|
||||
temporarySarifFiles.push(sarifFile);
|
||||
ranCustom = true;
|
||||
}
|
||||
}
|
||||
if (temporarySarifFiles.length > 0) {
|
||||
const sarifFile = path.join(sarifFolder, `${language}-custom.sarif`);
|
||||
fs.writeFileSync(sarifFile, combineSarifFiles(temporarySarifFiles));
|
||||
await injectLinesOfCode(sarifFile, language, locPromise);
|
||||
|
||||
if (ranCustom) {
|
||||
statusReport[`analyze_custom_queries_${language}_duration_ms`] =
|
||||
new Date().getTime() - startTimeCustom;
|
||||
}
|
||||
logger.endGroup();
|
||||
|
||||
// Print the LoC baseline and the summary results from database analyze for the standard
|
||||
// query suite and (if appropriate) each custom query suite.
|
||||
logger.startGroup(`Analysis summary for ${language}`);
|
||||
|
||||
printLinesOfCodeSummary(logger, language, await locPromise);
|
||||
logger.info(analysisSummaryBuiltIn);
|
||||
|
||||
for (const [i, customSummary] of customAnalysisSummaries.entries()) {
|
||||
if (customSummary.trim() === "") {
|
||||
continue;
|
||||
}
|
||||
const description =
|
||||
customAnalysisSummaries.length === 1
|
||||
? "custom queries"
|
||||
: `custom query suite ${i + 1}/${customAnalysisSummaries.length}`;
|
||||
logger.info(`Analysis summary for ${description}:`);
|
||||
logger.info("");
|
||||
logger.info(customSummary);
|
||||
logger.info("");
|
||||
}
|
||||
|
||||
logger.startGroup(`Interpreting results for ${language}`);
|
||||
const startTimeInterpretResults = new Date().getTime();
|
||||
const sarifFile = path.join(sarifFolder, `${language}.sarif`);
|
||||
const analysisSummary = await runInterpretResults(
|
||||
language,
|
||||
querySuitePaths,
|
||||
sarifFile
|
||||
);
|
||||
await injectLinesOfCode(sarifFile, language, locPromise);
|
||||
statusReport[`interpret_results_${language}_duration_ms`] =
|
||||
new Date().getTime() - startTimeInterpretResults;
|
||||
logger.endGroup();
|
||||
logger.info(analysisSummary);
|
||||
printLinesOfCodeSummary(logger, language, await locPromise);
|
||||
} catch (e) {
|
||||
logger.info(e);
|
||||
statusReport.analyze_failure_language = language;
|
||||
|
|
@ -253,13 +235,29 @@ export async function runQueries(
|
|||
|
||||
return statusReport;
|
||||
|
||||
async function runInterpretResults(
|
||||
language: Language,
|
||||
queries: string[],
|
||||
sarifFile: string
|
||||
): Promise<string> {
|
||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||
const codeql = getCodeQL(config.codeQLCmd);
|
||||
return await codeql.databaseInterpretResults(
|
||||
databasePath,
|
||||
queries,
|
||||
sarifFile,
|
||||
addSnippetsFlag,
|
||||
threadsFlag,
|
||||
automationDetailsId
|
||||
);
|
||||
}
|
||||
|
||||
async function runQueryGroup(
|
||||
language: Language,
|
||||
type: string,
|
||||
queries: string[],
|
||||
destinationFolder: string,
|
||||
searchPath: string | undefined
|
||||
): Promise<{ sarifFile: string; stdout: string }> {
|
||||
): Promise<string> {
|
||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||
// Pass the queries to codeql using a file instead of using the command
|
||||
// line to avoid command line length restrictions, particularly on windows.
|
||||
|
|
@ -270,24 +268,17 @@ export async function runQueries(
|
|||
fs.writeFileSync(querySuitePath, querySuiteContents);
|
||||
logger.debug(`Query suite file for ${language}...\n${querySuiteContents}`);
|
||||
|
||||
const sarifFile = path.join(destinationFolder, `${language}-${type}.sarif`);
|
||||
|
||||
const codeql = getCodeQL(config.codeQLCmd);
|
||||
const databaseAnalyzeStdout = await codeql.databaseAnalyze(
|
||||
await codeql.databaseRunQueries(
|
||||
databasePath,
|
||||
sarifFile,
|
||||
searchPath,
|
||||
querySuitePath,
|
||||
memoryFlag,
|
||||
addSnippetsFlag,
|
||||
threadsFlag,
|
||||
automationDetailsId
|
||||
threadsFlag
|
||||
);
|
||||
|
||||
logger.debug(
|
||||
`SARIF results for database ${language} created at "${sarifFile}"`
|
||||
);
|
||||
return { sarifFile, stdout: databaseAnalyzeStdout };
|
||||
logger.debug(`BQRS results produced for ${language} (queries: ${type})"`);
|
||||
return querySuitePath;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,22 +89,30 @@ export interface CodeQL {
|
|||
extraSearchPath: string | undefined
|
||||
): Promise<ResolveQueriesOutput>;
|
||||
/**
|
||||
* Run 'codeql database analyze'.
|
||||
* Run 'codeql database cleanup'.
|
||||
*/
|
||||
databaseAnalyze(
|
||||
databaseCleanup(databasePath: string, cleanupLevel: string): Promise<void>;
|
||||
/**
|
||||
* Run 'codeql database run-queries'.
|
||||
*/
|
||||
databaseRunQueries(
|
||||
databasePath: string,
|
||||
sarifFile: string,
|
||||
extraSearchPath: string | undefined,
|
||||
querySuite: string,
|
||||
querySuitePath: string,
|
||||
memoryFlag: string,
|
||||
threadsFlag: string
|
||||
): Promise<void>;
|
||||
/**
|
||||
* Run 'codeql database interpret-results'.
|
||||
*/
|
||||
databaseInterpretResults(
|
||||
databasePath: string,
|
||||
querySuitePaths: string[],
|
||||
sarifFile: string,
|
||||
addSnippetsFlag: string,
|
||||
threadsFlag: string,
|
||||
automationDetailsId: string | undefined
|
||||
): Promise<string>;
|
||||
/**
|
||||
* Run 'codeql database cleanup'.
|
||||
*/
|
||||
databaseCleanup(databasePath: string, cleanupLevel: string): Promise<void>;
|
||||
}
|
||||
|
||||
export interface ResolveLanguagesOutput {
|
||||
|
|
@ -484,8 +492,12 @@ export function setCodeQL(partialCodeql: Partial<CodeQL>): CodeQL {
|
|||
finalizeDatabase: resolveFunction(partialCodeql, "finalizeDatabase"),
|
||||
resolveLanguages: resolveFunction(partialCodeql, "resolveLanguages"),
|
||||
resolveQueries: resolveFunction(partialCodeql, "resolveQueries"),
|
||||
databaseAnalyze: resolveFunction(partialCodeql, "databaseAnalyze"),
|
||||
databaseCleanup: resolveFunction(partialCodeql, "databaseCleanup"),
|
||||
databaseRunQueries: resolveFunction(partialCodeql, "databaseRunQueries"),
|
||||
databaseInterpretResults: resolveFunction(
|
||||
partialCodeql,
|
||||
"databaseInterpretResults"
|
||||
),
|
||||
};
|
||||
return cachedCodeQL;
|
||||
}
|
||||
|
|
@ -708,40 +720,53 @@ function getCodeQLForCmd(cmd: string): CodeQL {
|
|||
throw new Error(`Unexpected output from codeql resolve queries: ${e}`);
|
||||
}
|
||||
},
|
||||
async databaseAnalyze(
|
||||
async databaseRunQueries(
|
||||
databasePath: string,
|
||||
sarifFile: string,
|
||||
extraSearchPath: string | undefined,
|
||||
querySuite: string,
|
||||
querySuitePath: string,
|
||||
memoryFlag: string,
|
||||
threadsFlag: string
|
||||
): Promise<void> {
|
||||
const args = [
|
||||
"database",
|
||||
"run-queries",
|
||||
memoryFlag,
|
||||
threadsFlag,
|
||||
databasePath,
|
||||
"--min-disk-free=1024", // Try to leave at least 1GB free
|
||||
"-v",
|
||||
...getExtraOptionsFromEnv(["database", "run-queries"]),
|
||||
];
|
||||
if (extraSearchPath !== undefined) {
|
||||
args.push("--additional-packs", extraSearchPath);
|
||||
}
|
||||
args.push(querySuitePath);
|
||||
await new toolrunner.ToolRunner(cmd, args).exec();
|
||||
},
|
||||
async databaseInterpretResults(
|
||||
databasePath: string,
|
||||
querySuitePaths: string[],
|
||||
sarifFile: string,
|
||||
addSnippetsFlag: string,
|
||||
threadsFlag: string,
|
||||
automationDetailsId: string | undefined
|
||||
): Promise<string> {
|
||||
const args = [
|
||||
"database",
|
||||
"analyze",
|
||||
memoryFlag,
|
||||
"interpret-results",
|
||||
threadsFlag,
|
||||
databasePath,
|
||||
"--min-disk-free=1024", // Try to leave at least 1GB free
|
||||
"--format=sarif-latest",
|
||||
"--sarif-multicause-markdown",
|
||||
"--print-metrics-summary",
|
||||
"--sarif-group-rules-by-pack",
|
||||
"-v",
|
||||
`--output=${sarifFile}`,
|
||||
addSnippetsFlag,
|
||||
// Enable progress verbosity so we log each query as it's interpreted. This aids debugging
|
||||
// when interpretation takes a while for one of the queries being analyzed.
|
||||
"-v",
|
||||
...getExtraOptionsFromEnv(["database", "analyze"]),
|
||||
...getExtraOptionsFromEnv(["database", "interpret-results"]),
|
||||
];
|
||||
if (extraSearchPath !== undefined) {
|
||||
args.push("--additional-packs", extraSearchPath);
|
||||
}
|
||||
if (automationDetailsId !== undefined) {
|
||||
args.push("--sarif-category", automationDetailsId);
|
||||
}
|
||||
args.push(querySuite);
|
||||
args.push(databasePath, ...querySuitePaths);
|
||||
// capture stdout, which contains analysis summaries
|
||||
let output = "";
|
||||
await new toolrunner.ToolRunner(cmd, args, {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue