update error_wrapper to take matcher array

This commit is contained in:
Nick Fyson 2020-09-01 16:35:08 +01:00
parent cd22abcda8
commit 7b7e0e12b7
6 changed files with 70 additions and 44 deletions

2
lib/codeql.js generated
View file

@ -304,7 +304,7 @@ function getCodeQLForCmd(cmd) {
'finalize',
...getExtraOptionsFromEnv(['database', 'finalize']),
databasePath
]);
], [[0, new RegExp("(No source code was seen during the build\\.|No JavaScript or TypeScript code found\\.)"), 'foo bar']]);
},
resolveQueries: async function (queries, extraSearchPath) {
const codeqlArgs = [

File diff suppressed because one or more lines are too long

46
lib/exec_wrapper.js generated
View file

@ -8,11 +8,23 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
const exec = __importStar(require("@actions/exec"));
async function exec_wrapper(commandLine, args, options) {
/**
* Wrapper for exec.exec which checks for specific return code and/or regex matches in console output.
* Output will be streamed to the live console as well as captured for subsequent processing.
* Returns promise with return code
*
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
* @param matchers defines specific codes and/or regexes that should lead to return of a custom error
* @param args optional arguments for tool. Escaping is handled by the lib.
* @param options optional exec options. See ExecOptions
* @returns Promise<number> exit code
*/
async function exec_wrapper(commandLine, args, matchers, options) {
var _a;
const originalListener = (_a = options) === null || _a === void 0 ? void 0 : _a.listeners;
let stdout = '';
let stderr = '';
// custom listeners to store stdout and stderr, while also replicating the behaviour of the passed listeners
const originalListener = (_a = options) === null || _a === void 0 ? void 0 : _a.listeners;
let listeners = {
stdout: (data) => {
var _a;
@ -37,29 +49,29 @@ async function exec_wrapper(commandLine, args, options) {
}
}
};
let returnCode;
// we capture the original return code and error so that (if no match is found) we can duplicate the behaviour
let originalReturnCode;
let originalError;
try {
returnCode = await exec.exec(commandLine, args, {
originalReturnCode = await exec.exec(commandLine, args, {
listeners: listeners,
...options
});
}
catch (e) {
returnCode = 1;
originalError = e;
originalReturnCode = 1; // TODO linter insists, but presumably there's a better way to do _all_ this...
}
if (returnCode === 0) {
throw new Error('The exit code was ' + returnCode + '?!');
if (matchers) {
for (const [customCode, regex, message] of matchers) {
if (customCode === originalReturnCode || regex.test(stderr) || regex.test(stdout)) {
throw new Error(message);
}
}
}
const regex = new RegExp("(No source code was seen during the build\\.|No JavaScript or TypeScript code found\\.)");
if (regex.test(stderr) || regex.test(stdout)) {
throw new Error(`No source code was found. This can occur if the specified build commands failed to compile or process any code.
- Confirm that there is some source code for the specified language in the project.
- For codebases written in Go, JavaScript, TypeScript, and Python, do not specify
an explicit --command.
- For other languages, the --command must specify a "clean" build which compiles
https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning`);
}
return returnCode;
if (originalError)
throw originalError;
return originalReturnCode;
}
exports.exec_wrapper = exec_wrapper;
//# sourceMappingURL=exec_wrapper.js.map

View file

@ -1 +1 @@
{"version":3,"file":"exec_wrapper.js","sourceRoot":"","sources":["../src/exec_wrapper.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAG/B,KAAK,UAAU,YAAY,CAAC,WAAmB,EAAE,IAAe,EAAE,OAAwB;;IAE/F,MAAM,gBAAgB,SAAG,OAAO,0CAAE,SAAS,CAAC;IAE5C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,IAAI,SAAS,GAAG;QACd,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,OAAA,gBAAgB,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC1C,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAC/B;iBAAM;gBACL,iFAAiF;gBACjF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC5B;QAEH,CAAC;QACD,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,OAAA,gBAAgB,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC1C,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAC/B;iBAAM;gBACL,iFAAiF;gBACjF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC5B;QACH,CAAC;KACF,CAAC;IAEF,IAAI,UAAkB,CAAC;IACvB,IAAI;QACF,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,CAC1B,WAAW,EACX,IAAI,EACJ;YACE,SAAS,EAAE,SAAS;YACpB,GAAG,OAAO;SACX,CAAC,CAAC;KACN;IAAC,OAAO,CAAC,EAAE;QACV,UAAU,GAAG,CAAC,CAAC;KAChB;IACD,IAAI,UAAU,KAAK,CAAC,EAAE;QACpB,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,UAAU,GAAG,IAAI,CAAC,CAAC;KAC3D;IAED,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,yFAAyF,CAAC,CAAC;IAEpH,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAG;QAC7C,MAAM,IAAI,KAAK,CAAC;;;;;yHAKqG,CAAC,CAAC;KACxH;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAzDD,oCAyDC"}
{"version":3,"file":"exec_wrapper.js","sourceRoot":"","sources":["../src/exec_wrapper.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAItC;;;;;;;;;;GAUG;AACI,KAAK,UAAU,YAAY,CAAC,WAAmB,EAAE,IAAe,EACpC,QAAqC,EACrC,OAAwB;;IAEzD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,4GAA4G;IAC5G,MAAM,gBAAgB,SAAG,OAAO,0CAAE,SAAS,CAAC;IAC5C,IAAI,SAAS,GAAG;QACd,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,OAAA,gBAAgB,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC1C,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAC/B;iBAAM;gBACL,iFAAiF;gBACjF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC5B;QAEH,CAAC;QACD,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,OAAA,gBAAgB,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC1C,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAC/B;iBAAM;gBACL,iFAAiF;gBACjF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC5B;QACH,CAAC;KACF,CAAC;IAEF,8GAA8G;IAC9G,IAAI,kBAA0B,CAAC;IAC/B,IAAI,aAA8B,CAAC;IACnC,IAAI;QACF,kBAAkB,GAAG,MAAM,IAAI,CAAC,IAAI,CAClC,WAAW,EACX,IAAI,EACJ;YACE,SAAS,EAAE,SAAS;YACpB,GAAG,OAAO;SACX,CAAC,CAAC;KACN;IAAC,OAAO,CAAC,EAAE;QACV,aAAa,GAAG,CAAC,CAAC;QAClB,kBAAkB,GAAG,CAAC,CAAC,CAAC,+EAA+E;KACxG;IAED,IAAI,QAAQ,EAAE;QACZ,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,QAAQ,EAAE;YACnD,IAAI,UAAU,KAAK,kBAAkB,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAG;gBAClF,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;aAC1B;SACF;KACF;IAED,IAAI,aAAa;QAAE,MAAM,aAAa,CAAC;IACvC,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAzDD,oCAyDC"}

View file

@ -391,12 +391,14 @@ function getCodeQLForCmd(cmd: string): CodeQL {
]);
},
finalizeDatabase: async function(databasePath: string) {
await exec_wrapper(cmd, [
'database',
'finalize',
...getExtraOptionsFromEnv(['database', 'finalize']),
databasePath
]);
await exec_wrapper(
cmd, [
'database',
'finalize',
...getExtraOptionsFromEnv(['database', 'finalize']),
databasePath
],
[[0, new RegExp("(No source code was seen during the build\\.|No JavaScript or TypeScript code found\\.)"), 'foo bar']]);
},
resolveQueries: async function(queries: string[], extraSearchPath: string | undefined) {
const codeqlArgs = [

View file

@ -1,13 +1,27 @@
import * as exec from '@actions/exec';
import * as im from '@actions/exec/lib/interfaces';
export async function exec_wrapper(commandLine: string, args?: string[], options?: im.ExecOptions): Promise<number> {
const originalListener = options?.listeners;
/**
* Wrapper for exec.exec which checks for specific return code and/or regex matches in console output.
* Output will be streamed to the live console as well as captured for subsequent processing.
* Returns promise with return code
*
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
* @param matchers defines specific codes and/or regexes that should lead to return of a custom error
* @param args optional arguments for tool. Escaping is handled by the lib.
* @param options optional exec options. See ExecOptions
* @returns Promise<number> exit code
*/
export async function exec_wrapper(commandLine: string, args?: string[],
matchers?: [[number, RegExp, string]],
options?: im.ExecOptions): Promise<number> {
let stdout = '';
let stderr = '';
// custom listeners to store stdout and stderr, while also replicating the behaviour of the passed listeners
const originalListener = options?.listeners;
let listeners = {
stdout: (data: Buffer) => {
stdout += data.toString();
@ -30,9 +44,11 @@ export async function exec_wrapper(commandLine: string, args?: string[], options
}
};
let returnCode: number;
// we capture the original return code and error so that (if no match is found) we can duplicate the behaviour
let originalReturnCode: number;
let originalError: Error|undefined;
try {
returnCode = await exec.exec(
originalReturnCode = await exec.exec(
commandLine,
args,
{
@ -40,22 +56,18 @@ export async function exec_wrapper(commandLine: string, args?: string[], options
...options
});
} catch (e) {
returnCode = 1;
}
if (returnCode === 0) {
throw new Error('The exit code was ' + returnCode + '?!');
originalError = e;
originalReturnCode = 1; // TODO linter insists, but presumably there's a better way to do _all_ this...
}
const regex = new RegExp("(No source code was seen during the build\\.|No JavaScript or TypeScript code found\\.)");
if (regex.test(stderr) || regex.test(stdout) ) {
throw new Error(`No source code was found. This can occur if the specified build commands failed to compile or process any code.
- Confirm that there is some source code for the specified language in the project.
- For codebases written in Go, JavaScript, TypeScript, and Python, do not specify
an explicit --command.
- For other languages, the --command must specify a "clean" build which compiles
https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning`);
if (matchers) {
for (const [customCode, regex, message] of matchers) {
if (customCode === originalReturnCode || regex.test(stderr) || regex.test(stdout) ) {
throw new Error(message);
}
}
}
return returnCode;
if (originalError) throw originalError;
return originalReturnCode;
}