give better error messages
This commit is contained in:
parent
fe3dbb7e64
commit
dcebdd6441
6 changed files with 129 additions and 6 deletions
22
lib/config-utils.js
generated
22
lib/config-utils.js
generated
|
|
@ -105,6 +105,24 @@ class Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.Config = Config;
|
exports.Config = Config;
|
||||||
|
// Regex validating stars in paths or paths-ignore entries.
|
||||||
|
// The intention is to only allow ** to appear when immediately
|
||||||
|
// preceded and followed by a slash.
|
||||||
|
const pathStarsRegex = /.*(?:\*\*[^/].*|\*\*$|[^/]\*\*.*)/;
|
||||||
|
// Checks that a paths of paths-ignore entry is valid, possibly modifying it
|
||||||
|
// to make it valid, or if not possible then throws an error.
|
||||||
|
function validateAndSanitisePath(originalPath, propertyName, configFile) {
|
||||||
|
let path = originalPath;
|
||||||
|
if (path.endsWith('/**')) {
|
||||||
|
path = path.substring(0, path.length - 2);
|
||||||
|
}
|
||||||
|
if (path.match(pathStarsRegex)) {
|
||||||
|
throw new Error(getConfigFilePropertyError(configFile, propertyName, '"' + originalPath + '" contains an invalid "**" wildcard. ' +
|
||||||
|
'They must be immediately preceeded and followed by a slash as in "/**/".'));
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
exports.validateAndSanitisePath = validateAndSanitisePath;
|
||||||
function getNameInvalid(configFile) {
|
function getNameInvalid(configFile) {
|
||||||
return getConfigFilePropertyError(configFile, NAME_PROPERTY, 'must be a non-empty string');
|
return getConfigFilePropertyError(configFile, NAME_PROPERTY, 'must be a non-empty string');
|
||||||
}
|
}
|
||||||
|
|
@ -216,7 +234,7 @@ async function initConfig() {
|
||||||
if (typeof path !== "string" || path === '') {
|
if (typeof path !== "string" || path === '') {
|
||||||
throw new Error(getPathsIgnoreInvalid(configFile));
|
throw new Error(getPathsIgnoreInvalid(configFile));
|
||||||
}
|
}
|
||||||
config.pathsIgnore.push(path);
|
config.pathsIgnore.push(validateAndSanitisePath(path, PATHS_IGNORE_PROPERTY, configFile));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (PATHS_PROPERTY in parsedYAML) {
|
if (PATHS_PROPERTY in parsedYAML) {
|
||||||
|
|
@ -227,7 +245,7 @@ async function initConfig() {
|
||||||
if (typeof path !== "string" || path === '') {
|
if (typeof path !== "string" || path === '') {
|
||||||
throw new Error(getPathsInvalid(configFile));
|
throw new Error(getPathsInvalid(configFile));
|
||||||
}
|
}
|
||||||
config.paths.push(path);
|
config.paths.push(validateAndSanitisePath(path, PATHS_PROPERTY, configFile));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
37
lib/config-utils.test.js
generated
37
lib/config-utils.test.js
generated
|
|
@ -265,4 +265,41 @@ doInvalidQueryUsesTest("foo@master", c => configUtils.getQueryUsesInvalid(c, "fo
|
||||||
doInvalidQueryUsesTest("https://github.com/foo/bar@master", c => configUtils.getQueryUsesInvalid(c, "https://github.com/foo/bar@master"));
|
doInvalidQueryUsesTest("https://github.com/foo/bar@master", c => configUtils.getQueryUsesInvalid(c, "https://github.com/foo/bar@master"));
|
||||||
doInvalidQueryUsesTest("./foo", c => configUtils.getLocalPathDoesNotExist(c, "foo"));
|
doInvalidQueryUsesTest("./foo", c => configUtils.getLocalPathDoesNotExist(c, "foo"));
|
||||||
doInvalidQueryUsesTest("./..", c => configUtils.getLocalPathOutsideOfRepository(c, ".."));
|
doInvalidQueryUsesTest("./..", c => configUtils.getLocalPathOutsideOfRepository(c, ".."));
|
||||||
|
const validPaths = [
|
||||||
|
'foo',
|
||||||
|
'foo/',
|
||||||
|
'foo/**',
|
||||||
|
'foo/**/',
|
||||||
|
'foo/**/**',
|
||||||
|
'foo/**/bar/**/baz',
|
||||||
|
'**/',
|
||||||
|
'**/foo',
|
||||||
|
'/foo',
|
||||||
|
];
|
||||||
|
const invalidPaths = [
|
||||||
|
'a/***/b',
|
||||||
|
'a/**b',
|
||||||
|
'a/b**',
|
||||||
|
'**',
|
||||||
|
];
|
||||||
|
ava_1.default('path validations', t => {
|
||||||
|
// Dummy values to pass to validateAndSanitisePath
|
||||||
|
const propertyName = 'paths';
|
||||||
|
const configFile = './.github/codeql/config.yml';
|
||||||
|
for (const path of validPaths) {
|
||||||
|
t.truthy(configUtils.validateAndSanitisePath(path, propertyName, configFile));
|
||||||
|
}
|
||||||
|
for (const path of invalidPaths) {
|
||||||
|
t.throws(() => configUtils.validateAndSanitisePath(path, propertyName, configFile));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ava_1.default('path sanitisation', t => {
|
||||||
|
// Dummy values to pass to validateAndSanitisePath
|
||||||
|
const propertyName = 'paths';
|
||||||
|
const configFile = './.github/codeql/config.yml';
|
||||||
|
// Valid paths are not modified
|
||||||
|
t.deepEqual(configUtils.validateAndSanitisePath('foo/bar', propertyName, configFile), 'foo/bar');
|
||||||
|
// Trailing stars are stripped
|
||||||
|
t.deepEqual(configUtils.validateAndSanitisePath('foo/**', propertyName, configFile), 'foo/');
|
||||||
|
});
|
||||||
//# sourceMappingURL=config-utils.test.js.map
|
//# sourceMappingURL=config-utils.test.js.map
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -343,3 +343,49 @@ doInvalidQueryUsesTest(
|
||||||
doInvalidQueryUsesTest(
|
doInvalidQueryUsesTest(
|
||||||
"./..",
|
"./..",
|
||||||
c => configUtils.getLocalPathOutsideOfRepository(c, ".."));
|
c => configUtils.getLocalPathOutsideOfRepository(c, ".."));
|
||||||
|
|
||||||
|
const validPaths = [
|
||||||
|
'foo',
|
||||||
|
'foo/',
|
||||||
|
'foo/**',
|
||||||
|
'foo/**/',
|
||||||
|
'foo/**/**',
|
||||||
|
'foo/**/bar/**/baz',
|
||||||
|
'**/',
|
||||||
|
'**/foo',
|
||||||
|
'/foo',
|
||||||
|
];
|
||||||
|
const invalidPaths = [
|
||||||
|
'a/***/b',
|
||||||
|
'a/**b',
|
||||||
|
'a/b**',
|
||||||
|
'**',
|
||||||
|
];
|
||||||
|
test('path validations', t => {
|
||||||
|
// Dummy values to pass to validateAndSanitisePath
|
||||||
|
const propertyName = 'paths';
|
||||||
|
const configFile = './.github/codeql/config.yml';
|
||||||
|
|
||||||
|
for (const path of validPaths) {
|
||||||
|
t.truthy(configUtils.validateAndSanitisePath(path, propertyName, configFile));
|
||||||
|
}
|
||||||
|
for (const path of invalidPaths) {
|
||||||
|
t.throws(() => configUtils.validateAndSanitisePath(path, propertyName, configFile));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('path sanitisation', t => {
|
||||||
|
// Dummy values to pass to validateAndSanitisePath
|
||||||
|
const propertyName = 'paths';
|
||||||
|
const configFile = './.github/codeql/config.yml';
|
||||||
|
|
||||||
|
// Valid paths are not modified
|
||||||
|
t.deepEqual(
|
||||||
|
configUtils.validateAndSanitisePath('foo/bar', propertyName, configFile),
|
||||||
|
'foo/bar');
|
||||||
|
|
||||||
|
// Trailing stars are stripped
|
||||||
|
t.deepEqual(
|
||||||
|
configUtils.validateAndSanitisePath('foo/**', propertyName, configFile),
|
||||||
|
'foo/');
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,28 @@ export class Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regex validating stars in paths or paths-ignore entries.
|
||||||
|
// The intention is to only allow ** to appear when immediately
|
||||||
|
// preceded and followed by a slash.
|
||||||
|
const pathStarsRegex = /.*(?:\*\*[^/].*|\*\*$|[^/]\*\*.*)/;
|
||||||
|
|
||||||
|
// Checks that a paths of paths-ignore entry is valid, possibly modifying it
|
||||||
|
// to make it valid, or if not possible then throws an error.
|
||||||
|
export function validateAndSanitisePath(originalPath: string, propertyName: string, configFile: string): string {
|
||||||
|
let path = originalPath;
|
||||||
|
if (path.endsWith('/**')) {
|
||||||
|
path = path.substring(0, path.length - 2);
|
||||||
|
}
|
||||||
|
if (path.match(pathStarsRegex)) {
|
||||||
|
throw new Error(getConfigFilePropertyError(
|
||||||
|
configFile,
|
||||||
|
propertyName,
|
||||||
|
'"' + originalPath + '" contains an invalid "**" wildcard. ' +
|
||||||
|
'They must be immediately preceeded and followed by a slash as in "/**/".'));
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
export function getNameInvalid(configFile: string): string {
|
export function getNameInvalid(configFile: string): string {
|
||||||
return getConfigFilePropertyError(configFile, NAME_PROPERTY, 'must be a non-empty string');
|
return getConfigFilePropertyError(configFile, NAME_PROPERTY, 'must be a non-empty string');
|
||||||
}
|
}
|
||||||
|
|
@ -243,7 +265,7 @@ async function initConfig(): Promise<Config> {
|
||||||
if (typeof path !== "string" || path === '') {
|
if (typeof path !== "string" || path === '') {
|
||||||
throw new Error(getPathsIgnoreInvalid(configFile));
|
throw new Error(getPathsIgnoreInvalid(configFile));
|
||||||
}
|
}
|
||||||
config.pathsIgnore.push(path);
|
config.pathsIgnore.push(validateAndSanitisePath(path, PATHS_IGNORE_PROPERTY, configFile));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,7 +277,7 @@ async function initConfig(): Promise<Config> {
|
||||||
if (typeof path !== "string" || path === '') {
|
if (typeof path !== "string" || path === '') {
|
||||||
throw new Error(getPathsInvalid(configFile));
|
throw new Error(getPathsInvalid(configFile));
|
||||||
}
|
}
|
||||||
config.paths.push(path);
|
config.paths.push(validateAndSanitisePath(path, PATHS_PROPERTY, configFile));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue