Extract language appropriately in analyze step when build mode specified
This commit is contained in:
parent
db6e5fff06
commit
0fe34bd39a
23 changed files with 205 additions and 61 deletions
|
|
@ -13,6 +13,7 @@ import {
|
|||
getCodeQL,
|
||||
} from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { BuildMode } from "./config-utils";
|
||||
import { addDiagnostic, makeDiagnostic } from "./diagnostics";
|
||||
import { EnvVar } from "./environment";
|
||||
import {
|
||||
|
|
@ -23,6 +24,7 @@ import {
|
|||
import { isScannedLanguage, Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { DatabaseCreationTimings, EventReport } from "./status-report";
|
||||
import { ToolsFeature } from "./tools-features";
|
||||
import { endTracingForCluster } from "./tracer-config";
|
||||
import { validateSarifFileSchema } from "./upload-lib";
|
||||
import * as util from "./util";
|
||||
|
|
@ -166,29 +168,49 @@ async function setupPythonExtractor(
|
|||
process.env["LGTM_PYTHON_SETUP_VERSION"] = output;
|
||||
}
|
||||
|
||||
export async function createdDBForScannedLanguages(
|
||||
export async function runExtraction(
|
||||
codeql: CodeQL,
|
||||
config: configUtils.Config,
|
||||
logger: Logger,
|
||||
features: FeatureEnablement,
|
||||
) {
|
||||
for (const language of config.languages) {
|
||||
if (
|
||||
isScannedLanguage(language) &&
|
||||
!dbIsFinalized(config, language, logger)
|
||||
) {
|
||||
logger.startGroup(`Extracting ${language}`);
|
||||
if (dbIsFinalized(config, language, logger)) {
|
||||
logger.debug(
|
||||
`Database for ${language} has already been finalized, skipping extraction.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shouldExtractLanguage(config, language)) {
|
||||
logger.startGroup(`Extracting ${language}`);
|
||||
if (language === Language.python) {
|
||||
await setupPythonExtractor(logger, features, codeql);
|
||||
}
|
||||
|
||||
await codeql.extractScannedLanguage(config, language);
|
||||
if (
|
||||
config.buildMode &&
|
||||
(await codeql.supportsFeature(ToolsFeature.TraceCommandUseBuildMode))
|
||||
) {
|
||||
await codeql.extractUsingBuildMode(config, language);
|
||||
} else {
|
||||
await codeql.extractScannedLanguage(config, language);
|
||||
}
|
||||
logger.endGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function shouldExtractLanguage(
|
||||
config: configUtils.Config,
|
||||
language: Language,
|
||||
): boolean {
|
||||
return (
|
||||
config.buildMode === BuildMode.None ||
|
||||
config.buildMode === BuildMode.Autobuild ||
|
||||
(!config.buildMode && isScannedLanguage(language))
|
||||
);
|
||||
}
|
||||
|
||||
export function dbIsFinalized(
|
||||
config: configUtils.Config,
|
||||
language: Language,
|
||||
|
|
@ -218,7 +240,7 @@ async function finalizeDatabaseCreation(
|
|||
const codeql = await getCodeQL(config.codeQLCmd);
|
||||
|
||||
const extractionStart = performance.now();
|
||||
await createdDBForScannedLanguages(codeql, config, logger, features);
|
||||
await runExtraction(codeql, config, logger, features);
|
||||
const extractionTime = performance.now() - extractionStart;
|
||||
|
||||
const trapImportStart = performance.now();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {
|
|||
} from "./actions-util";
|
||||
import { getGitHubVersion } from "./api-client";
|
||||
import { determineAutobuildLanguages, runAutobuild } from "./autobuild";
|
||||
import { getCodeQL } from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { Language } from "./languages";
|
||||
import { Logger, getActionsLogger } from "./logging";
|
||||
|
|
@ -87,7 +88,9 @@ async function run() {
|
|||
);
|
||||
}
|
||||
|
||||
languages = await determineAutobuildLanguages(config, logger);
|
||||
const codeql = await getCodeQL(config.codeQLCmd);
|
||||
|
||||
languages = await determineAutobuildLanguages(codeql, config, logger);
|
||||
if (languages !== undefined) {
|
||||
const workingDirectory = getOptionalInput("working-directory");
|
||||
if (workingDirectory) {
|
||||
|
|
|
|||
|
|
@ -4,17 +4,29 @@ import { getTemporaryDirectory, getWorkflowEventName } from "./actions-util";
|
|||
import { getGitHubVersion } from "./api-client";
|
||||
import { CodeQL, getCodeQL } from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { BuildMode } from "./config-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { Feature, featureConfig, Features } from "./feature-flags";
|
||||
import { isTracedLanguage, Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { parseRepositoryNwo } from "./repository";
|
||||
import { ToolsFeature } from "./tools-features";
|
||||
import { getRequiredEnvParam } from "./util";
|
||||
|
||||
export async function determineAutobuildLanguages(
|
||||
codeql: CodeQL,
|
||||
config: configUtils.Config,
|
||||
logger: Logger,
|
||||
): Promise<Language[] | undefined> {
|
||||
if (
|
||||
(config.buildMode === BuildMode.None &&
|
||||
(await codeql.supportsFeature(ToolsFeature.TraceCommandUseBuildMode))) ||
|
||||
config.buildMode === BuildMode.Manual
|
||||
) {
|
||||
logger.info(`Using ${config.buildMode} build mode, nothing to autobuild.`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Attempt to find a language to autobuild
|
||||
// We want pick the dominant language in the repo from the ones we're able to build
|
||||
// The languages are sorted in order specified by user or by lines of code if we got
|
||||
|
|
|
|||
|
|
@ -114,6 +114,11 @@ export interface CodeQL {
|
|||
* and running the language extractor.
|
||||
*/
|
||||
extractScannedLanguage(config: Config, language: Language): Promise<void>;
|
||||
/**
|
||||
* Extract code with 'codeql database trace-command --use-build-mode'. This can only be used when
|
||||
* the database specifies a build mode. This requires the `traceCommandUseBuildMode` tool feature.
|
||||
*/
|
||||
extractUsingBuildMode(config: Config, language: Language): Promise<void>;
|
||||
/**
|
||||
* Finalize a database using 'codeql database finalize'.
|
||||
*/
|
||||
|
|
@ -474,6 +479,10 @@ export function setCodeQL(partialCodeql: Partial<CodeQL>): CodeQL {
|
|||
partialCodeql,
|
||||
"extractScannedLanguage",
|
||||
),
|
||||
extractUsingBuildMode: resolveFunction(
|
||||
partialCodeql,
|
||||
"extractUsingBuildMode",
|
||||
),
|
||||
finalizeDatabase: resolveFunction(partialCodeql, "finalizeDatabase"),
|
||||
resolveLanguages: resolveFunction(partialCodeql, "resolveLanguages"),
|
||||
betterResolveLanguages: resolveFunction(
|
||||
|
|
@ -690,6 +699,16 @@ export async function getCodeQLForCmd(
|
|||
util.getCodeQLDatabasePath(config, language),
|
||||
]);
|
||||
},
|
||||
async extractUsingBuildMode(config: Config, language: Language) {
|
||||
await runTool(cmd, [
|
||||
"database",
|
||||
"trace-command",
|
||||
"--use-build-mode",
|
||||
...(await getTrapCachingExtractorConfigArgsForLang(config, language)),
|
||||
...getExtraOptionsFromEnv(["database", "trace-command"]),
|
||||
util.getCodeQLDatabasePath(config, language),
|
||||
]);
|
||||
},
|
||||
async finalizeDatabase(
|
||||
databasePath: string,
|
||||
threadsFlag: string,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
setCodeQL,
|
||||
} from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { BuildMode } from "./config-utils";
|
||||
import { Language } from "./languages";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { parseRepositoryNwo } from "./repository";
|
||||
|
|
@ -323,7 +324,7 @@ test("load non-empty input", async (t) => {
|
|||
// And the config we expect it to parse to
|
||||
const expectedConfig: configUtils.Config = {
|
||||
languages: [Language.javascript],
|
||||
buildMode: "none",
|
||||
buildMode: BuildMode.None,
|
||||
originalUserInput: {
|
||||
name: "my config",
|
||||
"disable-default-queries": true,
|
||||
|
|
|
|||
|
|
@ -72,6 +72,12 @@ interface IncludeQueryFilter {
|
|||
include: Record<string, string[] | string>;
|
||||
}
|
||||
|
||||
export enum BuildMode {
|
||||
None = "none",
|
||||
Autobuild = "autobuild",
|
||||
Manual = "manual",
|
||||
}
|
||||
|
||||
/**
|
||||
* Format of the parsed config file.
|
||||
*/
|
||||
|
|
@ -83,7 +89,7 @@ export interface Config {
|
|||
/**
|
||||
* Build mode, if set. Currently only a single build mode is supported per job.
|
||||
*/
|
||||
buildMode: string | undefined;
|
||||
buildMode: BuildMode | undefined;
|
||||
/**
|
||||
* A unaltered copy of the original user input.
|
||||
* Mainly intended to be used for status reporting.
|
||||
|
|
@ -466,7 +472,7 @@ export async function getDefaultConfig({
|
|||
|
||||
return {
|
||||
languages,
|
||||
buildMode: buildModeInput,
|
||||
buildMode: validateBuildModeInput(buildModeInput),
|
||||
originalUserInput: {},
|
||||
tempDir,
|
||||
codeQLCmd: codeql.getPath(),
|
||||
|
|
@ -554,7 +560,7 @@ async function loadConfig({
|
|||
|
||||
return {
|
||||
languages,
|
||||
buildMode: buildModeInput,
|
||||
buildMode: validateBuildModeInput(buildModeInput),
|
||||
originalUserInput: parsedYAML,
|
||||
tempDir,
|
||||
codeQLCmd: codeql.getPath(),
|
||||
|
|
@ -1056,3 +1062,20 @@ export async function wrapEnvironment(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
function validateBuildModeInput(
|
||||
buildModeInput: string | undefined,
|
||||
): BuildMode | undefined {
|
||||
if (buildModeInput === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!Object.values(BuildMode).includes(buildModeInput as BuildMode)) {
|
||||
throw new UserError(
|
||||
`Invalid build mode: '${buildModeInput}'. Supported build modes are: ${Object.values(
|
||||
BuildMode,
|
||||
).join(", ")}.`,
|
||||
);
|
||||
}
|
||||
return buildModeInput as BuildMode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ export enum ToolsFeature {
|
|||
BuildModeOption = "buildModeOption",
|
||||
IndirectTracingSupportsStaticBinaries = "indirectTracingSupportsStaticBinaries",
|
||||
SetsCodeqlRunnerEnvVar = "setsCodeqlRunnerEnvVar",
|
||||
TraceCommandUseBuildMode = "traceCommandUseBuildMode",
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue