Factor out groupLanguagesByExtractor

This commit is contained in:
Henry Mercer 2023-09-22 18:55:52 +01:00
parent d0c18ba23e
commit 431174f620
3 changed files with 64 additions and 30 deletions

40
lib/workflow.js generated
View file

@ -78,6 +78,27 @@ exports.WorkflowErrors = toCodedErrors({
MissingPushHook: `Please specify an on.push hook to analyze and see code scanning alerts from the default branch on the Security tab.`,
CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.`,
});
/**
* Groups the given list of CodeQL languages by their extractor name.
*
* Resolves to `undefined` if the CodeQL version does not support language aliasing.
*/
async function groupLanguagesByExtractor(languages, codeql) {
const resolveResult = await codeql.betterResolveLanguages();
if (!resolveResult.aliases) {
return undefined;
}
const aliases = resolveResult.aliases;
const languagesByExtractor = {};
for (const language of languages) {
const extractorName = aliases[language] || language;
if (!languagesByExtractor[extractorName]) {
languagesByExtractor[extractorName] = [];
}
languagesByExtractor[extractorName].push(language);
}
return languagesByExtractor;
}
async function getWorkflowErrors(doc, codeql) {
const errors = [];
const jobName = process.env.GITHUB_JOB;
@ -86,19 +107,12 @@ async function getWorkflowErrors(doc, codeql) {
if (job?.strategy?.matrix?.language) {
const matrixLanguages = job.strategy.matrix.language;
if (Array.isArray(matrixLanguages)) {
const resolveResult = await codeql.betterResolveLanguages();
if (resolveResult.aliases) {
const aliases = resolveResult.aliases;
// Map extractors to entries in the `language` matrix parameter. This will allow us to
// detect languages which are analyzed in more than one job.
const matrixLanguagesByExtractor = {};
for (const language of matrixLanguages) {
const extractorName = aliases[language] || language;
if (!matrixLanguagesByExtractor[extractorName]) {
matrixLanguagesByExtractor[extractorName] = [];
}
matrixLanguagesByExtractor[extractorName].push(language);
}
// Map extractors to entries in the `language` matrix parameter. This will allow us to
// detect languages which are analyzed in more than one job.
const matrixLanguagesByExtractor = await groupLanguagesByExtractor(matrixLanguages, codeql);
// If the CodeQL version does not support language aliasing, then `matrixLanguagesByExtractor`
// will be `undefined`. In this case, we cannot detect duplicate languages in the matrix.
if (matrixLanguagesByExtractor !== undefined) {
// Check for duplicate languages in the matrix
for (const [extractor, languages] of Object.entries(matrixLanguagesByExtractor)) {
if (languages.length > 1) {

File diff suppressed because one or more lines are too long

View file

@ -106,6 +106,33 @@ export const WorkflowErrors = toCodedErrors({
CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.`,
});
/**
* Groups the given list of CodeQL languages by their extractor name.
*
* Resolves to `undefined` if the CodeQL version does not support language aliasing.
*/
async function groupLanguagesByExtractor(
languages: string[],
codeql: CodeQL,
): Promise<{ [extractorName: string]: string[] } | undefined> {
const resolveResult = await codeql.betterResolveLanguages();
if (!resolveResult.aliases) {
return undefined;
}
const aliases = resolveResult.aliases;
const languagesByExtractor: {
[extractorName: string]: string[];
} = {};
for (const language of languages) {
const extractorName = aliases[language] || language;
if (!languagesByExtractor[extractorName]) {
languagesByExtractor[extractorName] = [];
}
languagesByExtractor[extractorName].push(language);
}
return languagesByExtractor;
}
export async function getWorkflowErrors(
doc: Workflow,
codeql: CodeQL,
@ -120,22 +147,15 @@ export async function getWorkflowErrors(
if (job?.strategy?.matrix?.language) {
const matrixLanguages = job.strategy.matrix.language;
if (Array.isArray(matrixLanguages)) {
const resolveResult = await codeql.betterResolveLanguages();
if (resolveResult.aliases) {
const aliases = resolveResult.aliases;
// Map extractors to entries in the `language` matrix parameter. This will allow us to
// detect languages which are analyzed in more than one job.
const matrixLanguagesByExtractor: {
[extractorName: string]: string[];
} = {};
for (const language of matrixLanguages) {
const extractorName = aliases[language] || language;
if (!matrixLanguagesByExtractor[extractorName]) {
matrixLanguagesByExtractor[extractorName] = [];
}
matrixLanguagesByExtractor[extractorName].push(language);
}
// Map extractors to entries in the `language` matrix parameter. This will allow us to
// detect languages which are analyzed in more than one job.
const matrixLanguagesByExtractor = await groupLanguagesByExtractor(
matrixLanguages,
codeql,
);
// If the CodeQL version does not support language aliasing, then `matrixLanguagesByExtractor`
// will be `undefined`. In this case, we cannot detect duplicate languages in the matrix.
if (matrixLanguagesByExtractor !== undefined) {
// Check for duplicate languages in the matrix
for (const [extractor, languages] of Object.entries(
matrixLanguagesByExtractor,