Move language functions in dedicated package

This commit is contained in:
Marco Gario
2020-09-11 12:01:16 +02:00
parent 588a28d3b5
commit 7b29d2e0a5
15 changed files with 215 additions and 202 deletions
+6 -6
View File
@@ -7,8 +7,8 @@ import sinon from 'sinon';
import * as api from './api-client';
import { getCachedCodeQL, setCodeQL } from './codeql';
import * as configUtils from './config-utils';
import { Language } from "./languages";
import { getRunnerLogger } from "./logging";
import { getLanguages, getNoLanguagesError, getUnknownLanguagesError, Language } from './languages';
import { getRunnerLogger } from './logging';
import {setupTests} from './testing-utils';
import * as util from './util';
@@ -740,7 +740,7 @@ test("No detected languages", async t => {
mockListLanguages([]);
try {
await configUtils.getLanguages(
await getLanguages(
undefined,
{ owner: 'github', repo: 'example ' },
'token',
@@ -748,7 +748,7 @@ test("No detected languages", async t => {
getRunnerLogger(true));
throw new Error('initConfig did not throw error');
} catch (err) {
t.deepEqual(err, new Error(configUtils.getNoLanguagesError()));
t.deepEqual(err, new Error(getNoLanguagesError()));
}
});
@@ -756,7 +756,7 @@ test("No detected languages", async t => {
test("Unknown languages", async t => {
const languages = 'ruby,english';
try {
await configUtils.getLanguages(
await getLanguages(
languages,
{ owner: 'github', repo: 'example ' },
'token',
@@ -764,7 +764,7 @@ test("Unknown languages", async t => {
getRunnerLogger(true));
throw new Error('initConfig did not throw error');
} catch (err) {
t.deepEqual(err, new Error(configUtils.getUnknownLanguagesError(['ruby', 'english'])));
t.deepEqual(err, new Error(getUnknownLanguagesError(['ruby', 'english'])));
}
});
+2 -101
View File
@@ -5,9 +5,9 @@ import * as path from 'path';
import * as api from './api-client';
import { CodeQL, ResolveQueriesOutput } from './codeql';
import * as externalQueries from "./external-queries";
import { Language, parseLanguage } from './languages';
import { Language } from './languages';
import { Logger } from './logging';
import { RepositoryNwo } from './repository';
// Property names from the user-supplied config file.
const NAME_PROPERTY = 'name';
@@ -441,105 +441,6 @@ function getConfigFilePropertyError(configFile: string | undefined, property: st
}
}
export function getNoLanguagesError(): string {
return "Did not detect any languages to analyze. " +
"Please update input in workflow or check that GitHub detects the correct languages in your repository.";
}
export function getUnknownLanguagesError(languages: string[]): string {
return "Did not recognise the following languages: " + languages.join(', ');
}
/**
* Gets the set of languages in the current repository
*/
async function getLanguagesInRepo(
repository: RepositoryNwo,
githubAuth: string,
githubUrl: string,
logger: Logger): Promise<Language[]> {
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
const response = await api.getApiClient(githubAuth, githubUrl, true).repos.listLanguages({
owner: repository.owner,
repo: repository.repo
});
logger.debug("Languages API response: " + JSON.stringify(response));
// The GitHub API is going to return languages in order of popularity,
// When we pick a language to autobuild we want to pick the most popular traced language
// Since sets in javascript maintain insertion order, using a set here and then splatting it
// into an array gives us an array of languages ordered by popularity
let languages: Set<Language> = new Set();
for (let lang of Object.keys(response.data)) {
let parsedLang = parseLanguage(lang);
if (parsedLang !== undefined) {
languages.add(parsedLang);
}
}
return [...languages];
}
/**
* Get the languages to analyse.
*
* The result is obtained from the action input parameter 'languages' if that
* has been set, otherwise it is deduced as all languages in the repo that
* can be analysed.
*
* If no languages could be detected from either the workflow or the repository
* then throw an error.
*/
export async function getLanguages(
// Maybe move to init.ts
languagesInput: string | undefined,
repository: RepositoryNwo,
githubAuth: string,
githubUrl: string,
logger: Logger): Promise<Language[]> {
// Obtain from action input 'languages' if set
let languages = (languagesInput || "")
.split(',')
.map(x => x.trim())
.filter(x => x.length > 0);
logger.info("Languages from configuration: " + JSON.stringify(languages));
if (languages.length === 0) {
// Obtain languages as all languages in the repo that can be analysed
languages = await getLanguagesInRepo(
repository,
githubAuth,
githubUrl,
logger);
logger.info("Automatically detected languages: " + JSON.stringify(languages));
}
// If the languages parameter was not given and no languages were
// detected then fail here as this is a workflow configuration error.
if (languages.length === 0) {
throw new Error(getNoLanguagesError());
}
// Make sure they are supported
const parsedLanguages: Language[] = [];
const unknownLanguages: string[] = [];
for (let language of languages) {
const parsedLanguage = parseLanguage(language);
if (parsedLanguage === undefined) {
unknownLanguages.push(language);
} else if (parsedLanguages.indexOf(parsedLanguage) === -1) {
parsedLanguages.push(parsedLanguage);
}
}
if (unknownLanguages.length > 0) {
throw new Error(getUnknownLanguagesError(unknownLanguages));
}
return parsedLanguages;
}
async function addQueriesFromWorkflow(
codeQL: CodeQL,
queriesInput: string,
+2 -1
View File
@@ -3,6 +3,7 @@ import * as core from '@actions/core';
import { CodeQL } from './codeql';
import * as configUtils from './config-utils';
import { initCodeQL, initConfig, injectWindowsTracer, runInit } from './init';
import { getLanguages } from './languages';
import { getActionsLogger } from './logging';
import { parseRepositoryNwo } from './repository';
import * as util from './util';
@@ -59,7 +60,7 @@ async function run() {
}
const repositoryNWO = parseRepositoryNwo(util.getRequiredEnvParam('GITHUB_REPOSITORY'));
const languages = await configUtils.getLanguages(
const languages = await getLanguages(
core.getInput('languages'),
repositoryNWO,
core.getInput('token'),
+106
View File
@@ -1,3 +1,9 @@
import * as api from './api-client';
import { Logger } from './logging';
import { RepositoryNwo } from './repository';
// All the languages supported by CodeQL
export enum Language {
csharp = 'csharp',
@@ -42,3 +48,103 @@ export function isTracedLanguage(language: Language): boolean {
export function isScannedLanguage(language: Language): boolean {
return !isTracedLanguage(language);
}
export function getNoLanguagesError(): string {
return "Did not detect any languages to analyze. " +
"Please update input in workflow or check that GitHub detects the correct languages in your repository.";
}
export function getUnknownLanguagesError(languages: string[]): string {
return "Did not recognise the following languages: " + languages.join(', ');
}
/**
* Get the languages to analyse.
*
* The result is obtained from the action input parameter 'languages' if that
* has been set, otherwise it is deduced as all languages in the repo that
* can be analysed.
*
* If no languages could be detected from either the workflow or the repository
* then throw an error.
*/
export async function getLanguages(
languagesInput: string | undefined,
repository: RepositoryNwo,
githubAuth: string,
githubUrl: string,
logger: Logger): Promise<Language[]> {
// Obtain from action input 'languages' if set
let languages = (languagesInput || "")
.split(',')
.map(x => x.trim())
.filter(x => x.length > 0);
logger.info("Languages from configuration: " + JSON.stringify(languages));
if (languages.length === 0) {
// Obtain languages as all languages in the repo that can be analysed
languages = await getLanguagesInRepo(
repository,
githubAuth,
githubUrl,
logger);
logger.info("Automatically detected languages: " + JSON.stringify(languages));
}
// If the languages parameter was not given and no languages were
// detected then fail here as this is a workflow configuration error.
if (languages.length === 0) {
throw new Error(getNoLanguagesError());
}
// Make sure they are supported
const parsedLanguages: Language[] = [];
const unknownLanguages: string[] = [];
for (let language of languages) {
const parsedLanguage = parseLanguage(language);
if (parsedLanguage === undefined) {
unknownLanguages.push(language);
} else if (parsedLanguages.indexOf(parsedLanguage) === -1) {
parsedLanguages.push(parsedLanguage);
}
}
if (unknownLanguages.length > 0) {
throw new Error(getUnknownLanguagesError(unknownLanguages));
}
return parsedLanguages;
}
/**
* Gets the set of languages in the current repository
*/
async function getLanguagesInRepo(
repository: RepositoryNwo,
githubAuth: string,
githubUrl: string,
logger: Logger): Promise<Language[]> {
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
const response = await api.getApiClient(githubAuth, githubUrl, true).repos.listLanguages({
owner: repository.owner,
repo: repository.repo
});
logger.debug("Languages API response: " + JSON.stringify(response));
// The GitHub API is going to return languages in order of popularity,
// When we pick a language to autobuild we want to pick the most popular traced language
// Since sets in javascript maintain insertion order, using a set here and then splatting it
// into an array gives us an array of languages ordered by popularity
let languages: Set<Language> = new Set();
for (let lang of Object.keys(response.data)) {
let parsedLang = parseLanguage(lang);
if (parsedLang !== undefined) {
languages.add(parsedLang);
}
}
return [...languages];
}
+2 -2
View File
@@ -6,9 +6,9 @@ import * as path from 'path';
import { runAnalyze } from './analyze';
import { determineAutobuildLanguage, runAutobuild } from './autobuild';
import { CodeQL, getCodeQL } from './codeql';
import { Config, getConfig, getLanguages } from './config-utils';
import { Config, getConfig } from './config-utils';
import { initCodeQL, initConfig, injectWindowsTracer, runInit } from './init';
import { Language, parseLanguage } from './languages';
import { getLanguages, Language, parseLanguage } from './languages';
import { getRunnerLogger } from './logging';
import { parseRepositoryNwo } from './repository';
import * as upload_lib from './upload-lib';