Skip to content

Commit 2a8725d

Browse files
committed
let the codeql env decide the supported languages
1 parent 503f298 commit 2a8725d

11 files changed

+136
-127
lines changed

src/analyze.test.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { runQueries } from "./analyze";
1010
import { setCodeQL } from "./codeql";
1111
import { Config } from "./config-utils";
1212
import * as count from "./count-loc";
13-
import { Language } from "./languages";
13+
import { KnownLanguage } from "./languages";
1414
import { getRunnerLogger } from "./logging";
1515
import { setupTests, setupActionsVars } from "./testing-utils";
1616
import * as util from "./util";
@@ -21,8 +21,8 @@ setupTests(test);
2121
// and correct case of builtin or custom. Also checks the correct search
2222
// paths are set in the database analyze invocation.
2323
test("status report fields and search path setting", async (t) => {
24-
const mockLinesOfCode = Object.values(Language).reduce((obj, lang, i) => {
25-
// use a different line count for each language
24+
const mockLinesOfCode = Object.values(KnownLanguage).reduce((obj, lang, i) => {
25+
// use a different line count for each KnownLanguage
2626
obj[lang] = i + 1;
2727
return obj;
2828
}, {});
@@ -35,21 +35,21 @@ test("status report fields and search path setting", async (t) => {
3535
const addSnippetsFlag = "";
3636
const threadsFlag = "";
3737
const packs = {
38-
[Language.cpp]: [
38+
[KnownLanguage.cpp]: [
3939
{
4040
packName: "a/b",
4141
version: clean("1.0.0")!,
4242
},
4343
],
44-
[Language.java]: [
44+
[KnownLanguage.java]: [
4545
{
4646
packName: "c/d",
4747
version: clean("2.0.0")!,
4848
},
4949
],
5050
};
5151

52-
for (const language of Object.values(Language)) {
52+
for (const language of Object.values(KnownLanguage)) {
5353
setCodeQL({
5454
packDownload: async () => ({ packs: [] }),
5555
databaseRunQueries: async (
@@ -203,7 +203,7 @@ test("status report fields and search path setting", async (t) => {
203203

204204
function verifyLineCounts(tmpDir: string) {
205205
// eslint-disable-next-line github/array-foreach
206-
Object.keys(Language).forEach((lang, i) => {
206+
Object.keys(KnownLanguage).forEach((lang, i) => {
207207
verifyLineCountForFile(path.join(tmpDir, `${lang}.sarif`), i + 1);
208208
});
209209
}
@@ -249,14 +249,14 @@ test("status report fields and search path setting", async (t) => {
249249
version: "2.0.0",
250250
},
251251
];
252-
for (const lang of Object.values(Language)) {
252+
for (const lang of Object.values(KnownLanguage)) {
253253
t.deepEqual(readContents(`${lang}-queries-builtin.qls`), qlsContent);
254254
t.deepEqual(readContents(`${lang}-queries-custom-0.qls`), qlsContent);
255255
t.deepEqual(readContents(`${lang}-queries-custom-1.qls`), qlsContent2);
256256
const packSuiteName = `${lang}-queries-packs.qls`;
257-
if (lang === Language.cpp) {
257+
if (lang === KnownLanguage.cpp) {
258258
t.deepEqual(readContents(packSuiteName), qlsPackContentCpp);
259-
} else if (lang === Language.java) {
259+
} else if (lang === KnownLanguage.java) {
260260
t.deepEqual(readContents(packSuiteName), qlsPackContentJava);
261261
} else {
262262
t.false(

src/analyze.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as analysisPaths from "./analysis-paths";
88
import { CODEQL_VERSION_COUNTS_LINES, getCodeQL } from "./codeql";
99
import * as configUtils from "./config-utils";
1010
import { countLoc } from "./count-loc";
11-
import { isScannedLanguage, Language } from "./languages";
11+
import { isScannedLanguage, KnownLanguage, Language } from "./languages";
1212
import { Logger } from "./logging";
1313
import * as sharedEnv from "./shared-environment";
1414
import * as util from "./util";
@@ -124,7 +124,7 @@ async function createdDBForScannedLanguages(
124124
) {
125125
logger.startGroup(`Extracting ${language}`);
126126

127-
if (language === Language.python) {
127+
if (language === KnownLanguage.python) {
128128
await setupPythonExtractor(logger);
129129
}
130130

src/config-utils.test.ts

+37-37
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import * as sinon from "sinon";
99
import * as api from "./api-client";
1010
import { getCachedCodeQL, setCodeQL } from "./codeql";
1111
import * as configUtils from "./config-utils";
12-
import { Language } from "./languages";
12+
import { KnownLanguage, Language } from "./languages";
1313
import { getRunnerLogger } from "./logging";
1414
import { setupTests } from "./testing-utils";
1515
import * as util from "./util";
@@ -299,7 +299,7 @@ test("load non-empty input", async (t) => {
299299

300300
// And the config we expect it to parse to
301301
const expectedConfig: configUtils.Config = {
302-
languages: [Language.javascript],
302+
languages: [KnownLanguage.javascript],
303303
queries: {
304304
javascript: {
305305
builtin: [],
@@ -998,7 +998,7 @@ test("Unknown languages", async (t) => {
998998
} catch (err) {
999999
t.deepEqual(
10001000
err,
1001-
new Error(configUtils.getUnknownLanguagesError(["rubbish", "english"]))
1001+
new Error(configUtils.getUnsupportedLanguagesError(["rubbish", "english"]))
10021002
);
10031003
}
10041004
});
@@ -1044,7 +1044,7 @@ test("Config specifies packages", async (t) => {
10441044
getRunnerLogger(true)
10451045
);
10461046
t.deepEqual(packs as unknown, {
1047-
[Language.javascript]: [
1047+
[KnownLanguage.javascript]: [
10481048
{
10491049
packName: "a/b",
10501050
version: clean("1.2.3"),
@@ -1102,13 +1102,13 @@ test("Config specifies packages for multiple languages", async (t) => {
11021102
getRunnerLogger(true)
11031103
);
11041104
t.deepEqual(packs as unknown, {
1105-
[Language.javascript]: [
1105+
[KnownLanguage.javascript]: [
11061106
{
11071107
packName: "a/b",
11081108
version: clean("1.2.3"),
11091109
},
11101110
],
1111-
[Language.python]: [
1111+
[KnownLanguage.python]: [
11121112
{
11131113
packName: "c/d",
11141114
version: clean("1.2.3"),
@@ -1377,8 +1377,8 @@ parsePacksErrorMacro.title = (providedTitle: string) =>
13771377
function invalidPackNameMacro(t: ExecutionContext<unknown>, name: string) {
13781378
parsePacksErrorMacro(
13791379
t,
1380-
{ [Language.cpp]: [name] },
1381-
[Language.cpp],
1380+
{ [KnownLanguage.cpp]: [name] },
1381+
[KnownLanguage.cpp],
13821382
new RegExp(
13831383
`The configuration file "/a/b" is invalid: property "packs" "${name}" is not a valid pack`
13841384
)
@@ -1388,8 +1388,8 @@ invalidPackNameMacro.title = (_: string, arg: string) =>
13881388
`Invalid pack string: ${arg}`;
13891389

13901390
test("no packs", parsePacksMacro, {}, [], {});
1391-
test("two packs", parsePacksMacro, ["a/b", "c/[email protected]"], [Language.cpp], {
1392-
[Language.cpp]: [
1391+
test("two packs", parsePacksMacro, ["a/b", "c/[email protected]"], [KnownLanguage.cpp], {
1392+
[KnownLanguage.cpp]: [
13931393
{ packName: "a/b", version: undefined },
13941394
{ packName: "c/d", version: clean("1.2.3") },
13951395
],
@@ -1398,9 +1398,9 @@ test(
13981398
"two packs with spaces",
13991399
parsePacksMacro,
14001400
[" a/b ", " c/[email protected] "],
1401-
[Language.cpp],
1401+
[KnownLanguage.cpp],
14021402
{
1403-
[Language.cpp]: [
1403+
[KnownLanguage.cpp]: [
14041404
{ packName: "a/b", version: undefined },
14051405
{ packName: "c/d", version: clean("1.2.3") },
14061406
],
@@ -1410,16 +1410,16 @@ test(
14101410
"two packs with language",
14111411
parsePacksMacro,
14121412
{
1413-
[Language.cpp]: ["a/b", "c/[email protected]"],
1414-
[Language.java]: ["d/e", "f/[email protected]"],
1413+
[KnownLanguage.cpp]: ["a/b", "c/[email protected]"],
1414+
[KnownLanguage.java]: ["d/e", "f/[email protected]"],
14151415
},
1416-
[Language.cpp, Language.java, Language.csharp],
1416+
[KnownLanguage.cpp, KnownLanguage.java, KnownLanguage.csharp],
14171417
{
1418-
[Language.cpp]: [
1418+
[KnownLanguage.cpp]: [
14191419
{ packName: "a/b", version: undefined },
14201420
{ packName: "c/d", version: clean("1.2.3") },
14211421
],
1422-
[Language.java]: [
1422+
[KnownLanguage.java]: [
14231423
{ packName: "d/e", version: undefined },
14241424
{ packName: "f/g", version: clean("1.2.3") },
14251425
],
@@ -1430,21 +1430,21 @@ test(
14301430
"no language",
14311431
parsePacksErrorMacro,
14321432
1433-
[Language.java, Language.python],
1433+
[KnownLanguage.java, KnownLanguage.python],
14341434
/The configuration file "\/a\/b" is invalid: property "packs" must split packages by language/
14351435
);
14361436
test(
14371437
"invalid language",
14381438
parsePacksErrorMacro,
1439-
{ [Language.java]: ["c/d"] },
1440-
[Language.cpp],
1439+
{ [KnownLanguage.java]: ["c/d"] },
1440+
[KnownLanguage.cpp],
14411441
/The configuration file "\/a\/b" is invalid: property "packs" has "java", but it is not one of the languages to analyze/
14421442
);
14431443
test(
14441444
"not an array",
14451445
parsePacksErrorMacro,
1446-
{ [Language.cpp]: "c/d" },
1447-
[Language.cpp],
1446+
{ [KnownLanguage.cpp]: "c/d" },
1447+
[KnownLanguage.cpp],
14481448
/The configuration file "\/a\/b" is invalid: property "packs" must be an array of non-empty strings/
14491449
);
14501450

@@ -1496,18 +1496,18 @@ function parseInputAndConfigErrorMacro(
14961496
parseInputAndConfigErrorMacro.title = (providedTitle: string) =>
14971497
`Parse Packs input and config Error: ${providedTitle}`;
14981498

1499-
test("input only", parseInputAndConfigMacro, {}, " c/d ", [Language.cpp], {
1500-
[Language.cpp]: [{ packName: "c/d", version: undefined }],
1499+
test("input only", parseInputAndConfigMacro, {}, " c/d ", [KnownLanguage.cpp], {
1500+
[KnownLanguage.cpp]: [{ packName: "c/d", version: undefined }],
15011501
});
15021502

15031503
test(
15041504
"input only with multiple",
15051505
parseInputAndConfigMacro,
15061506
{},
15071507
"a/b , c/[email protected]",
1508-
[Language.cpp],
1508+
[KnownLanguage.cpp],
15091509
{
1510-
[Language.cpp]: [
1510+
[KnownLanguage.cpp]: [
15111511
{ packName: "a/b", version: undefined },
15121512
{ packName: "c/d", version: "1.2.3" },
15131513
],
@@ -1519,9 +1519,9 @@ test(
15191519
parseInputAndConfigMacro,
15201520
{},
15211521
" + a/b , c/[email protected] ",
1522-
[Language.cpp],
1522+
[KnownLanguage.cpp],
15231523
{
1524-
[Language.cpp]: [
1524+
[KnownLanguage.cpp]: [
15251525
{ packName: "a/b", version: undefined },
15261526
{ packName: "c/d", version: "1.2.3" },
15271527
],
@@ -1533,9 +1533,9 @@ test(
15331533
parseInputAndConfigMacro,
15341534
["a/b", "c/d"],
15351535
" ",
1536-
[Language.cpp],
1536+
[KnownLanguage.cpp],
15371537
{
1538-
[Language.cpp]: [
1538+
[KnownLanguage.cpp]: [
15391539
{ packName: "a/b", version: undefined },
15401540
{ packName: "c/d", version: undefined },
15411541
],
@@ -1547,9 +1547,9 @@ test(
15471547
parseInputAndConfigMacro,
15481548
["a/b", "c/d"],
15491549
" e/f, g/[email protected] ",
1550-
[Language.cpp],
1550+
[KnownLanguage.cpp],
15511551
{
1552-
[Language.cpp]: [
1552+
[KnownLanguage.cpp]: [
15531553
{ packName: "e/f", version: undefined },
15541554
{ packName: "g/h", version: "1.2.3" },
15551555
],
@@ -1561,9 +1561,9 @@ test(
15611561
parseInputAndConfigMacro,
15621562
["a/b", "c/d"],
15631563
" +e/f, g/[email protected] ",
1564-
[Language.cpp],
1564+
[KnownLanguage.cpp],
15651565
{
1566-
[Language.cpp]: [
1566+
[KnownLanguage.cpp]: [
15671567
{ packName: "e/f", version: undefined },
15681568
{ packName: "g/h", version: "1.2.3" },
15691569
{ packName: "a/b", version: undefined },
@@ -1586,7 +1586,7 @@ test(
15861586
parseInputAndConfigErrorMacro,
15871587
{},
15881588
"c/d",
1589-
[Language.cpp, Language.csharp],
1589+
[KnownLanguage.cpp, KnownLanguage.csharp],
15901590
/multi-language analysis/
15911591
);
15921592

@@ -1595,7 +1595,7 @@ test(
15951595
parseInputAndConfigErrorMacro,
15961596
{},
15971597
" + ",
1598-
[Language.cpp],
1598+
[KnownLanguage.cpp],
15991599
/remove the '\+'/
16001600
);
16011601

@@ -1604,7 +1604,7 @@ test(
16041604
parseInputAndConfigErrorMacro,
16051605
{},
16061606
" xxx",
1607-
[Language.cpp],
1607+
[KnownLanguage.cpp],
16081608
/"xxx" is not a valid pack/
16091609
);
16101610

src/config-utils.ts

+17-15
Original file line numberDiff line numberDiff line change
@@ -673,8 +673,8 @@ export function getNoLanguagesError(): string {
673673
);
674674
}
675675

676-
export function getUnknownLanguagesError(languages: string[]): string {
677-
return `Did not recognise the following languages: ${languages.join(", ")}`;
676+
export function getUnsupportedLanguagesError(languages: string[]): string {
677+
return `Does not support the following languages: ${languages.join(", ")}`;
678678
}
679679

680680
/**
@@ -714,8 +714,10 @@ async function getLanguagesInRepo(
714714
* has been set, otherwise it is deduced as all languages in the repo that
715715
* can be analysed.
716716
*
717-
* If no languages could be detected from either the workflow or the repository
717+
* If no supported languages could be detected from either the workflow or the repository
718718
* then throw an error.
719+
*
720+
* The set of supported languages is defined by the `codeql resolve languages` command.
719721
*/
720722
async function getLanguages(
721723
codeQL: CodeQL,
@@ -731,11 +733,11 @@ async function getLanguages(
731733
.filter((x) => x.length > 0);
732734
logger.info(`Languages from configuration: ${JSON.stringify(languages)}`);
733735

736+
const allSupportedLanguages = new Set(Object.keys(await codeQL.resolveLanguages()));
734737
if (languages.length === 0) {
735738
// Obtain languages as all languages in the repo that can be analysed
736739
languages = await getLanguagesInRepo(repository, apiDetails, logger);
737-
const availableLanguages = await codeQL.resolveLanguages();
738-
languages = languages.filter((value) => value in availableLanguages);
740+
languages = languages.filter((value) => allSupportedLanguages.has(value));
739741
logger.info(
740742
`Automatically detected languages: ${JSON.stringify(languages)}`
741743
);
@@ -748,21 +750,21 @@ async function getLanguages(
748750
}
749751

750752
// Make sure they are supported
751-
const parsedLanguages: Language[] = [];
752-
const unknownLanguages: string[] = [];
753+
const supportedLanguages: Language[] = [];
754+
const unsupportedLanguages: Language[] = [];
753755
for (const language of languages) {
754756
const parsedLanguage = parseLanguage(language);
755-
if (parsedLanguage === undefined) {
756-
unknownLanguages.push(language);
757-
} else if (parsedLanguages.indexOf(parsedLanguage) === -1) {
758-
parsedLanguages.push(parsedLanguage);
757+
if (!allSupportedLanguages.has(parsedLanguage)) {
758+
unsupportedLanguages.push(language);
759+
} else if (supportedLanguages.indexOf(parsedLanguage) === -1) {
760+
supportedLanguages.push(parsedLanguage);
759761
}
760762
}
761-
if (unknownLanguages.length > 0) {
762-
throw new Error(getUnknownLanguagesError(unknownLanguages));
763+
if (unsupportedLanguages.length > 0) {
764+
throw new Error(getUnsupportedLanguagesError(unsupportedLanguages));
763765
}
764766

765-
return parsedLanguages;
767+
return supportedLanguages;
766768
}
767769

768770
async function addQueriesFromWorkflow(
@@ -1071,7 +1073,7 @@ export function parsePacksFromConfig(
10711073
if (!Array.isArray(packsArr)) {
10721074
throw new Error(getPacksInvalid(configFile));
10731075
}
1074-
if (!languages.includes(lang as Language)) {
1076+
if (!languages.includes(lang)) {
10751077
throw new Error(getPacksRequireLanguage(lang, configFile));
10761078
}
10771079
packs[lang] = [];

0 commit comments

Comments
 (0)