mirror of
https://github.com/github/codeql-action.git
synced 2026-01-03 13:10:06 +08:00
Add analysis-kinds input and parse it
This commit is contained in:
36
src/analyses.test.ts
Normal file
36
src/analyses.test.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import test from "ava";
|
||||
|
||||
import {
|
||||
AnalysisKind,
|
||||
parseAnalysisKinds,
|
||||
supportedAnalysisKinds,
|
||||
} from "./analyses";
|
||||
import { ConfigurationError } from "./util";
|
||||
|
||||
test("All known analysis kinds can be parsed successfully", async (t) => {
|
||||
for (const analysisKind of supportedAnalysisKinds) {
|
||||
t.deepEqual(await parseAnalysisKinds(analysisKind), [analysisKind]);
|
||||
}
|
||||
});
|
||||
|
||||
test("Parsing analysis kinds returns unique results", async (t) => {
|
||||
const analysisKinds = await parseAnalysisKinds(
|
||||
"code-scanning,code-quality,code-scanning",
|
||||
);
|
||||
t.deepEqual(analysisKinds, [
|
||||
AnalysisKind.CodeScanning,
|
||||
AnalysisKind.CodeQuality,
|
||||
]);
|
||||
});
|
||||
|
||||
test("Parsing an unknown analysis kind fails with a configuration error", async (t) => {
|
||||
await t.throwsAsync(parseAnalysisKinds("code-scanning,foo"), {
|
||||
instanceOf: ConfigurationError,
|
||||
});
|
||||
});
|
||||
|
||||
test("Parsing analysis kinds requires at least one analysis kind", async (t) => {
|
||||
await t.throwsAsync(parseAnalysisKinds(","), {
|
||||
instanceOf: ConfigurationError,
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,40 @@
|
||||
import { ConfigurationError } from "./util";
|
||||
|
||||
export enum AnalysisKind {
|
||||
CodeScanning = "code-scanning",
|
||||
CodeQuality = "code-quality",
|
||||
}
|
||||
|
||||
// Exported for testing. A set of all known analysis kinds.
|
||||
export const supportedAnalysisKinds = new Set(Object.values(AnalysisKind));
|
||||
|
||||
/**
|
||||
* Parses a comma-separated string into a list of unique analysis kinds.
|
||||
* Throws a configuration error if the input contains unknown analysis kinds
|
||||
* or doesn't contain at least one element.
|
||||
*
|
||||
* @param input The comma-separated string to parse.
|
||||
* @returns The array of unique analysis kinds that were parsed from the input string.
|
||||
*/
|
||||
export async function parseAnalysisKinds(
|
||||
input: string,
|
||||
): Promise<AnalysisKind[]> {
|
||||
const components = input.split(",");
|
||||
|
||||
if (components.length < 1) {
|
||||
throw new ConfigurationError(
|
||||
"At least one analysis kind must be configured.",
|
||||
);
|
||||
}
|
||||
|
||||
for (const component of components) {
|
||||
if (!supportedAnalysisKinds.has(component as AnalysisKind)) {
|
||||
throw new ConfigurationError(`Unknown analysis kind: ${component}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Return all unique elements.
|
||||
return Array.from(
|
||||
new Set(components.map((component) => component as AnalysisKind)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import * as yaml from "js-yaml";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { AnalysisKind } from "./analyses";
|
||||
import * as api from "./api-client";
|
||||
import { CachingKind } from "./caching-utils";
|
||||
import { createStubCodeQL } from "./codeql";
|
||||
@@ -47,6 +48,7 @@ function createTestInitConfigInputs(
|
||||
return Object.assign(
|
||||
{},
|
||||
{
|
||||
analysisKindsInput: "code-scanning",
|
||||
languagesInput: undefined,
|
||||
queriesInput: undefined,
|
||||
qualityQueriesInput: undefined,
|
||||
@@ -322,6 +324,7 @@ test("load non-empty input", async (t) => {
|
||||
|
||||
// And the config we expect it to parse to
|
||||
const expectedConfig: configUtils.Config = {
|
||||
analysisKinds: [AnalysisKind.CodeScanning],
|
||||
languages: [KnownLanguage.javascript],
|
||||
buildMode: BuildMode.None,
|
||||
originalUserInput: {
|
||||
|
||||
@@ -6,6 +6,7 @@ import * as yaml from "js-yaml";
|
||||
import * as semver from "semver";
|
||||
|
||||
import { isAnalyzingPullRequest } from "./actions-util";
|
||||
import { AnalysisKind, parseAnalysisKinds } from "./analyses";
|
||||
import * as api from "./api-client";
|
||||
import { CachingKind, getCachingKind } from "./caching-utils";
|
||||
import { type CodeQL } from "./codeql";
|
||||
@@ -93,6 +94,10 @@ interface IncludeQueryFilter {
|
||||
* Format of the parsed config file.
|
||||
*/
|
||||
export interface Config {
|
||||
/**
|
||||
* Set of analysis kinds that are enabled.
|
||||
*/
|
||||
analysisKinds: AnalysisKind[];
|
||||
/**
|
||||
* Set of languages to run analysis for.
|
||||
*/
|
||||
@@ -483,6 +488,7 @@ export async function getRawLanguages(
|
||||
|
||||
/** Inputs required to initialize a configuration. */
|
||||
export interface InitConfigInputs {
|
||||
analysisKindsInput: string;
|
||||
languagesInput: string | undefined;
|
||||
queriesInput: string | undefined;
|
||||
qualityQueriesInput: string | undefined;
|
||||
@@ -511,6 +517,7 @@ export interface InitConfigInputs {
|
||||
* Get the default config, populated without user configuration file.
|
||||
*/
|
||||
export async function getDefaultConfig({
|
||||
analysisKindsInput,
|
||||
languagesInput,
|
||||
queriesInput,
|
||||
qualityQueriesInput,
|
||||
@@ -530,6 +537,8 @@ export async function getDefaultConfig({
|
||||
features,
|
||||
logger,
|
||||
}: InitConfigInputs): Promise<Config> {
|
||||
const analysisKinds = await parseAnalysisKinds(analysisKindsInput);
|
||||
|
||||
const languages = await getLanguages(
|
||||
codeql,
|
||||
languagesInput,
|
||||
@@ -560,6 +569,7 @@ export async function getDefaultConfig({
|
||||
);
|
||||
|
||||
return {
|
||||
analysisKinds,
|
||||
languages,
|
||||
buildMode,
|
||||
originalUserInput: {},
|
||||
|
||||
@@ -385,6 +385,7 @@ async function run() {
|
||||
}
|
||||
|
||||
config = await initConfig({
|
||||
analysisKindsInput: getRequiredInput("analysis-kinds"),
|
||||
languagesInput: getOptionalInput("languages"),
|
||||
queriesInput: getOptionalInput("queries"),
|
||||
qualityQueriesInput: getOptionalInput("quality-queries"),
|
||||
|
||||
Reference in New Issue
Block a user