Merge branch 'main' into language_parsing
This commit is contained in:
commit
574b5dc4e9
12 changed files with 284 additions and 8 deletions
|
|
@ -63,3 +63,35 @@ test('parse codeql bundle url version', t => {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('getExtraOptions works for explicit paths', t => {
|
||||
t.deepEqual(codeql.getExtraOptions({}, ['foo'], []), []);
|
||||
|
||||
t.deepEqual(codeql.getExtraOptions({foo: [42]}, ['foo'], []), ['42']);
|
||||
|
||||
t.deepEqual(codeql.getExtraOptions({foo: {bar: [42]}}, ['foo', 'bar'], []), ['42']);
|
||||
});
|
||||
|
||||
test('getExtraOptions works for wildcards', t => {
|
||||
t.deepEqual(codeql.getExtraOptions({'*': [42]}, ['foo'], []), ['42']);
|
||||
});
|
||||
|
||||
test('getExtraOptions works for wildcards and explicit paths', t => {
|
||||
let o1 = {'*': [42], foo: [87]};
|
||||
t.deepEqual(codeql.getExtraOptions(o1, ['foo'], []), ['42', '87']);
|
||||
|
||||
let o2 = {'*': [42], foo: [87]};
|
||||
t.deepEqual(codeql.getExtraOptions(o2, ['foo', 'bar'], []), ['42']);
|
||||
|
||||
let o3 = {'*': [42], foo: { '*': [87], bar: [99]}};
|
||||
let p = ['foo', 'bar'];
|
||||
t.deepEqual(codeql.getExtraOptions(o3, p, []), ['42', '87', '99']);
|
||||
});
|
||||
|
||||
test('getExtraOptions throws for bad content', t => {
|
||||
t.throws(() => codeql.getExtraOptions({'*': 42}, ['foo'], []));
|
||||
|
||||
t.throws(() => codeql.getExtraOptions({foo: 87}, ['foo'], []));
|
||||
|
||||
t.throws(() => codeql.getExtraOptions({'*': [42], foo: { '*': 87, bar: [99]}}, ['foo', 'bar'], []));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,6 +15,27 @@ import * as defaults from './defaults.json'; // Referenced from codeql-action-sy
|
|||
import { Language } from './languages';
|
||||
import * as util from './util';
|
||||
|
||||
type Options = (string|number|boolean)[];
|
||||
|
||||
/**
|
||||
* Extra command line options for the codeql commands.
|
||||
*/
|
||||
interface ExtraOptions {
|
||||
'*'?: Options;
|
||||
database?: {
|
||||
'*'?: Options,
|
||||
init?: Options,
|
||||
'trace-command'?: Options,
|
||||
analyze?: Options,
|
||||
finalize?: Options
|
||||
};
|
||||
resolve?: {
|
||||
'*'?: Options,
|
||||
extractor?: Options,
|
||||
queries?: Options
|
||||
};
|
||||
}
|
||||
|
||||
export interface CodeQL {
|
||||
/**
|
||||
* Get the directory where the CodeQL executable is located.
|
||||
|
|
@ -287,6 +308,7 @@ function getCodeQLForCmd(cmd: string): CodeQL {
|
|||
'trace-command',
|
||||
databasePath,
|
||||
...compilerSpecArg,
|
||||
...getExtraOptionsFromEnv(['database', 'trace-command']),
|
||||
process.execPath,
|
||||
path.resolve(__dirname, 'tracer-env.js'),
|
||||
envFile
|
||||
|
|
@ -300,6 +322,7 @@ function getCodeQLForCmd(cmd: string): CodeQL {
|
|||
databasePath,
|
||||
'--language=' + language,
|
||||
'--source-root=' + sourceRoot,
|
||||
...getExtraOptionsFromEnv(['database', 'init']),
|
||||
]);
|
||||
},
|
||||
runAutobuild: async function(language: Language) {
|
||||
|
|
@ -325,7 +348,8 @@ function getCodeQLForCmd(cmd: string): CodeQL {
|
|||
'resolve',
|
||||
'extractor',
|
||||
'--format=json',
|
||||
'--language=' + language
|
||||
'--language=' + language,
|
||||
...getExtraOptionsFromEnv(['resolve', 'extractor']),
|
||||
],
|
||||
{
|
||||
silent: true,
|
||||
|
|
@ -343,6 +367,7 @@ function getCodeQLForCmd(cmd: string): CodeQL {
|
|||
await exec.exec(cmd, [
|
||||
'database',
|
||||
'trace-command',
|
||||
...getExtraOptionsFromEnv(['database', 'trace-command']),
|
||||
databasePath,
|
||||
'--',
|
||||
traceCommand
|
||||
|
|
@ -352,6 +377,7 @@ function getCodeQLForCmd(cmd: string): CodeQL {
|
|||
await exec.exec(cmd, [
|
||||
'database',
|
||||
'finalize',
|
||||
...getExtraOptionsFromEnv(['database', 'finalize']),
|
||||
databasePath
|
||||
]);
|
||||
},
|
||||
|
|
@ -360,7 +386,8 @@ function getCodeQLForCmd(cmd: string): CodeQL {
|
|||
'resolve',
|
||||
'queries',
|
||||
...queries,
|
||||
'--format=bylanguage'
|
||||
'--format=bylanguage',
|
||||
...getExtraOptionsFromEnv(['resolve', 'queries'])
|
||||
];
|
||||
if (extraSearchPath !== undefined) {
|
||||
codeqlArgs.push('--search-path', extraSearchPath);
|
||||
|
|
@ -386,8 +413,58 @@ function getCodeQLForCmd(cmd: string): CodeQL {
|
|||
'--format=sarif-latest',
|
||||
'--output=' + sarifFile,
|
||||
'--no-sarif-add-snippets',
|
||||
...getExtraOptionsFromEnv(['database', 'analyze']),
|
||||
querySuite
|
||||
]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the options for `path` of `options` as an array of extra option strings.
|
||||
*/
|
||||
function getExtraOptionsFromEnv(path: string[]) {
|
||||
let options: ExtraOptions = util.getExtraOptionsEnvParam();
|
||||
return getExtraOptions(options, path, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the options for `path` of `options` as an array of extra option strings.
|
||||
*
|
||||
* - the special terminal step name '*' in `options` matches all path steps
|
||||
* - throws an exception if this conversion is impossible.
|
||||
*/
|
||||
export /* exported for testing */ function getExtraOptions(
|
||||
options: any,
|
||||
path: string[],
|
||||
pathInfo: string[]): string[] {
|
||||
/**
|
||||
* Gets `options` as an array of extra option strings.
|
||||
*
|
||||
* - throws an exception mentioning `pathInfo` if this conversion is impossible.
|
||||
*/
|
||||
function asExtraOptions(options: any, pathInfo: string[]): string[] {
|
||||
if (options === undefined) {
|
||||
return [];
|
||||
}
|
||||
if (!Array.isArray(options)) {
|
||||
const msg =
|
||||
`The extra options for '${pathInfo.join('.')}' ('${JSON.stringify(options)}') are not in an array.`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
return options.map(o => {
|
||||
const t = typeof o;
|
||||
if (t !== 'string' && t !== 'number' && t !== 'boolean') {
|
||||
const msg =
|
||||
`The extra option for '${pathInfo.join('.')}' ('${JSON.stringify(o)}') is not a primitive value.`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
return o + '';
|
||||
});
|
||||
}
|
||||
let all = asExtraOptions(options?.['*'], pathInfo.concat('*'));
|
||||
let specific = path.length === 0 ?
|
||||
asExtraOptions(options, pathInfo) :
|
||||
getExtraOptions(options?.[path[0]], path?.slice(1), pathInfo.concat(path[0]));
|
||||
return all.concat(specific);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,3 +116,37 @@ test('prepareEnvironment() when a local run', t => {
|
|||
|
||||
process.env.CODEQL_LOCAL_RUN = origLocalRun;
|
||||
});
|
||||
|
||||
test('getExtraOptionsEnvParam() succeeds on valid JSON with invalid options (for now)', t => {
|
||||
const origExtraOptions = process.env.CODEQL_ACTION_EXTRA_OPTIONS;
|
||||
|
||||
const options = {foo: 42};
|
||||
|
||||
process.env.CODEQL_ACTION_EXTRA_OPTIONS = JSON.stringify(options);
|
||||
|
||||
t.deepEqual(util.getExtraOptionsEnvParam(), <any>options);
|
||||
|
||||
process.env.CODEQL_ACTION_EXTRA_OPTIONS = origExtraOptions;
|
||||
});
|
||||
|
||||
|
||||
test('getExtraOptionsEnvParam() succeeds on valid options', t => {
|
||||
const origExtraOptions = process.env.CODEQL_ACTION_EXTRA_OPTIONS;
|
||||
|
||||
const options = { database: { init: ["--debug"] } };
|
||||
process.env.CODEQL_ACTION_EXTRA_OPTIONS =
|
||||
JSON.stringify(options);
|
||||
|
||||
t.deepEqual(util.getExtraOptionsEnvParam(), options);
|
||||
|
||||
process.env.CODEQL_ACTION_EXTRA_OPTIONS = origExtraOptions;
|
||||
});
|
||||
|
||||
test('getExtraOptionsEnvParam() fails on invalid JSON', t => {
|
||||
const origExtraOptions = process.env.CODEQL_ACTION_EXTRA_OPTIONS;
|
||||
|
||||
process.env.CODEQL_ACTION_EXTRA_OPTIONS = "{{invalid-json}}";
|
||||
t.throws(util.getExtraOptionsEnvParam);
|
||||
|
||||
process.env.CODEQL_ACTION_EXTRA_OPTIONS = origExtraOptions;
|
||||
});
|
||||
|
|
|
|||
20
src/util.ts
20
src/util.ts
|
|
@ -39,6 +39,26 @@ export function getRequiredEnvParam(paramName: string): string {
|
|||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extra options for the codeql commands.
|
||||
*/
|
||||
export function getExtraOptionsEnvParam(): object {
|
||||
const varName = 'CODEQL_ACTION_EXTRA_OPTIONS';
|
||||
const raw = process.env[varName];
|
||||
if (raw === undefined || raw.length === 0) {
|
||||
return {};
|
||||
}
|
||||
try {
|
||||
return JSON.parse(raw);
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
varName +
|
||||
' environment variable is set, but does not contain valid JSON: ' +
|
||||
e.message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function isLocalRun(): boolean {
|
||||
return !!process.env.CODEQL_LOCAL_RUN
|
||||
&& process.env.CODEQL_LOCAL_RUN !== 'false'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue