Introduce wrapper around codeql

This commit is contained in:
Robert Brignull
2020-06-26 17:22:19 +01:00
parent 8947510a57
commit c41d287cae
19 changed files with 533 additions and 272 deletions

73
lib/finalize-db.js generated
View File

@@ -8,10 +8,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const exec = __importStar(require("@actions/exec"));
const io = __importStar(require("@actions/io"));
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const codeql_1 = require("./codeql");
const configUtils = __importStar(require("./config-utils"));
const externalQueries = __importStar(require("./external-queries"));
const sharedEnv = __importStar(require("./shared-environment"));
@@ -36,57 +36,30 @@ function queryIsDisabled(language, query) {
return (DISABLED_BUILTIN_QUERIES[language] || [])
.some(disabledQuery => query.endsWith(disabledQuery));
}
async function createdDBForScannedLanguages(codeqlCmd, databaseFolder) {
async function createdDBForScannedLanguages(databaseFolder) {
const scannedLanguages = process.env[sharedEnv.CODEQL_ACTION_SCANNED_LANGUAGES];
if (scannedLanguages) {
const codeql = codeql_1.getCodeQL();
for (const language of scannedLanguages.split(',')) {
core.startGroup('Extracting ' + language);
// Get extractor location
let extractorPath = '';
await exec.exec(codeqlCmd, ['resolve', 'extractor', '--format=json', '--language=' + language], {
silent: true,
listeners: {
stdout: (data) => { extractorPath += data.toString(); },
stderr: (data) => { process.stderr.write(data); }
}
});
// Set trace command
const ext = process.platform === 'win32' ? '.cmd' : '.sh';
const traceCommand = path.resolve(JSON.parse(extractorPath), 'tools', 'autobuild' + ext);
// Run trace command
await exec.exec(codeqlCmd, ['database', 'trace-command', path.join(databaseFolder, language), '--', traceCommand]);
await codeql.extractScannedLanguage(databaseFolder, language);
core.endGroup();
}
}
}
async function finalizeDatabaseCreation(codeqlCmd, databaseFolder) {
await createdDBForScannedLanguages(codeqlCmd, databaseFolder);
async function finalizeDatabaseCreation(databaseFolder) {
await createdDBForScannedLanguages(databaseFolder);
const languages = process.env[sharedEnv.CODEQL_ACTION_LANGUAGES] || '';
const codeql = codeql_1.getCodeQL();
for (const language of languages.split(',')) {
core.startGroup('Finalizing ' + language);
await exec.exec(codeqlCmd, ['database', 'finalize', path.join(databaseFolder, language)]);
await codeql.finalizeDatabase(databaseFolder, language);
core.endGroup();
}
}
async function runResolveQueries(codeqlCmd, queries) {
let output = '';
const options = {
listeners: {
stdout: (data) => {
output += data.toString();
}
}
};
await exec.exec(codeqlCmd, [
'resolve',
'queries',
...queries,
'--format=bylanguage'
], options);
return JSON.parse(output);
}
async function resolveQueryLanguages(codeqlCmd, config) {
async function resolveQueryLanguages(config) {
let res = new Map();
const codeql = codeql_1.getCodeQL();
if (!config.disableDefaultQueries || config.additionalSuites.length !== 0) {
const suites = [];
for (const language of await util.getLanguages()) {
@@ -97,7 +70,7 @@ async function resolveQueryLanguages(codeqlCmd, config) {
suites.push(language + '-' + additionalSuite + '.qls');
}
}
const resolveQueriesOutputObject = await runResolveQueries(codeqlCmd, suites);
const resolveQueriesOutputObject = await codeql.resolveQueries(suites);
for (const [language, queries] of Object.entries(resolveQueriesOutputObject.byLanguage)) {
if (res[language] === undefined) {
res[language] = [];
@@ -106,7 +79,7 @@ async function resolveQueryLanguages(codeqlCmd, config) {
}
}
if (config.additionalQueries.length !== 0) {
const resolveQueriesOutputObject = await runResolveQueries(codeqlCmd, config.additionalQueries);
const resolveQueriesOutputObject = await codeql.resolveQueries(config.additionalQueries);
for (const [language, queries] of Object.entries(resolveQueriesOutputObject.byLanguage)) {
if (res[language] === undefined) {
res[language] = [];
@@ -127,8 +100,9 @@ async function resolveQueryLanguages(codeqlCmd, config) {
return res;
}
// Runs queries and creates sarif files in the given folder
async function runQueries(codeqlCmd, databaseFolder, sarifFolder, config) {
const queriesPerLanguage = await resolveQueryLanguages(codeqlCmd, config);
async function runQueries(databaseFolder, sarifFolder, config) {
const queriesPerLanguage = await resolveQueryLanguages(config);
const codeql = codeql_1.getCodeQL();
for (let database of fs.readdirSync(databaseFolder)) {
core.startGroup('Analyzing ' + database);
const queries = queriesPerLanguage[database] || [];
@@ -142,17 +116,7 @@ async function runQueries(codeqlCmd, databaseFolder, sarifFolder, config) {
fs.writeFileSync(querySuite, querySuiteContents);
core.debug('Query suite file for ' + database + '...\n' + querySuiteContents);
const sarifFile = path.join(sarifFolder, database + '.sarif');
await exec.exec(codeqlCmd, [
'database',
'analyze',
util.getMemoryFlag(),
util.getThreadsFlag(),
path.join(databaseFolder, database),
'--format=sarif-latest',
'--output=' + sarifFile,
'--no-sarif-add-snippets',
querySuite
]);
await codeql.databaseAnalyze(path.join(databaseFolder, database), sarifFile, querySuite);
core.debug('SARIF results for database ' + database + ' created at "' + sarifFile + '"');
core.endGroup();
}
@@ -165,15 +129,14 @@ async function run() {
const config = await configUtils.loadConfig();
core.exportVariable(sharedEnv.ODASA_TRACER_CONFIGURATION, '');
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];
const codeqlCmd = util.getRequiredEnvParam(sharedEnv.CODEQL_ACTION_CMD);
const databaseFolder = util.getRequiredEnvParam(sharedEnv.CODEQL_ACTION_DATABASE_DIR);
const sarifFolder = core.getInput('output');
await io.mkdirP(sarifFolder);
core.info('Finalizing database creation');
await finalizeDatabaseCreation(codeqlCmd, databaseFolder);
await finalizeDatabaseCreation(databaseFolder);
await externalQueries.checkoutExternalQueries(config);
core.info('Analyzing database');
await runQueries(codeqlCmd, databaseFolder, sarifFolder, config);
await runQueries(databaseFolder, sarifFolder, config);
if ('true' === core.getInput('upload')) {
if (!await upload_lib.upload(sarifFolder)) {
await util.reportActionFailed('finish', 'upload');