Allways get the config file with the api

This commit is contained in:
David Verdeguer
2020-08-12 10:02:13 +02:00
parent bcf676e52d
commit d96885a274
6 changed files with 60 additions and 125 deletions
+6 -23
View File
@@ -261,14 +261,6 @@ function getLocalPathDoesNotExist(configFile, localPath) {
return getConfigFilePropertyError(configFile, QUERIES_PROPERTY + '.' + QUERIES_USES_PROPERTY, 'is invalid as the local path "' + localPath + '" does not exist in the repository');
}
exports.getLocalPathDoesNotExist = getLocalPathDoesNotExist;
function getConfigFileOutsideWorkspaceErrorMessage(configFile) {
return 'The configuration file "' + configFile + '" is outside of the workspace';
}
exports.getConfigFileOutsideWorkspaceErrorMessage = getConfigFileOutsideWorkspaceErrorMessage;
function getConfigFileDoesNotExistErrorMessage(configFile) {
return 'The configuration file "' + configFile + '" does not exist';
}
exports.getConfigFileDoesNotExistErrorMessage = getConfigFileDoesNotExistErrorMessage;
function getConfigFileRepoFormatInvalidMessage(configFile) {
let error = 'The configuration file "' + configFile + '" is not a supported remote file reference.';
error += ' Expected format <owner>/<repository>/<file-path>@<ref>';
@@ -409,10 +401,12 @@ exports.getDefaultConfig = getDefaultConfig;
async function loadConfig(configFile) {
let parsedYAML;
if (isLocal(configFile)) {
// Treat the config file as relative to the workspace
const workspacePath = util.getRequiredEnvParam('GITHUB_WORKSPACE');
configFile = path.resolve(workspacePath, configFile);
parsedYAML = getLocalConfig(configFile, workspacePath);
// Even if its local we want to retrieve the config using the api.
// For using the api we have to remove the starting "./"
const configFilePath = configFile.substr(2);
const remote = util.getRequiredEnvParam("GITHUB_REPOSITORY") + "/" + configFilePath
+ "@" + util.getRef();
parsedYAML = await getRemoteConfig(remote);
}
else {
parsedYAML = await getRemoteConfig(configFile);
@@ -519,17 +513,6 @@ function isLocal(configPath) {
}
return (configPath.indexOf("@") === -1);
}
function getLocalConfig(configFile, workspacePath) {
// Error if the config file is now outside of the workspace
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
throw new Error(getConfigFileOutsideWorkspaceErrorMessage(configFile));
}
// Error if the file does not exist
if (!fs.existsSync(configFile)) {
throw new Error(getConfigFileDoesNotExistErrorMessage(configFile));
}
return yaml.safeLoad(fs.readFileSync(configFile, 'utf8'));
}
async function getRemoteConfig(configFile) {
// retrieve the various parts of the config location, and ensure they're present
const format = new RegExp('(?<owner>[^/]+)/(?<repo>[^/]+)/(?<path>[^@]+)@(?<ref>.*)');
File diff suppressed because one or more lines are too long
+22 -35
View File
@@ -100,20 +100,6 @@ ava_1.default("loading config saves config", async (t) => {
t.deepEqual(config1, config2);
});
});
ava_1.default("load input outside of workspace", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
process.env['RUNNER_TEMP'] = tmpDir;
process.env['GITHUB_WORKSPACE'] = tmpDir;
setInput('config-file', '../input');
try {
await configUtils.initConfig();
throw new Error('initConfig did not throw error');
}
catch (err) {
t.deepEqual(err, new Error(configUtils.getConfigFileOutsideWorkspaceErrorMessage(path.join(tmpDir, '../input'))));
}
});
});
ava_1.default("load non-local input with invalid repo syntax", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
process.env['RUNNER_TEMP'] = tmpDir;
@@ -129,26 +115,12 @@ ava_1.default("load non-local input with invalid repo syntax", async (t) => {
}
});
});
ava_1.default("load non-existent input", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
process.env['RUNNER_TEMP'] = tmpDir;
process.env['GITHUB_WORKSPACE'] = tmpDir;
t.false(fs.existsSync(path.join(tmpDir, 'input')));
setInput('config-file', 'input');
setInput('languages', 'javascript');
try {
await configUtils.initConfig();
throw new Error('initConfig did not throw error');
}
catch (err) {
t.deepEqual(err, new Error(configUtils.getConfigFileDoesNotExistErrorMessage(path.join(tmpDir, 'input'))));
}
});
});
ava_1.default("load non-empty input", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
process.env['RUNNER_TEMP'] = tmpDir;
process.env['GITHUB_WORKSPACE'] = tmpDir;
process.env['GITHUB_REPOSITORY'] = "octo-org/codeql-config";
process.env["GITHUB_REF"] = "refs/heads/main";
CodeQL.setCodeQL({
resolveQueries: async function () {
return {
@@ -174,6 +146,10 @@ ava_1.default("load non-empty input", async (t) => {
- b
paths:
- c/d`;
const dummyResponse = {
content: Buffer.from(inputFileContents).toString("base64"),
};
const spyGetContents = mockGetContents(dummyResponse);
fs.mkdirSync(path.join(tmpDir, 'foo'));
// And the config we expect it to parse to
const expectedConfig = {
@@ -189,18 +165,20 @@ ava_1.default("load non-empty input", async (t) => {
paths: ['c/d'],
},
};
fs.writeFileSync(path.join(tmpDir, 'input'), inputFileContents, 'utf8');
setInput('config-file', 'input');
setInput('languages', 'javascript');
const actualConfig = await configUtils.initConfig();
// Should exactly equal the object we constructed earlier
t.deepEqual(actualConfig, expectedConfig);
t.assert(spyGetContents.called);
});
});
ava_1.default("default queries are used", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
process.env['RUNNER_TEMP'] = tmpDir;
process.env['GITHUB_WORKSPACE'] = tmpDir;
process.env['GITHUB_REPOSITORY'] = "octo-org/codeql-config";
process.env["GITHUB_REF"] = "refs/heads/main";
// Check that the default behaviour is to add the default queries.
// In this case if a config file is specified but does not include
// the disable-default-queries field.
@@ -227,8 +205,11 @@ ava_1.default("default queries are used", async (t) => {
const inputFileContents = `
paths:
- foo`;
const dummyResponse = {
content: Buffer.from(inputFileContents).toString("base64"),
};
const spyGetContents = mockGetContents(dummyResponse);
fs.mkdirSync(path.join(tmpDir, 'foo'));
fs.writeFileSync(path.join(tmpDir, 'input'), inputFileContents, 'utf8');
setInput('config-file', 'input');
setInput('languages', 'javascript');
await configUtils.initConfig();
@@ -236,6 +217,7 @@ ava_1.default("default queries are used", async (t) => {
t.deepEqual(resolveQueriesArgs.length, 1);
t.deepEqual(resolveQueriesArgs[0].queries, ['javascript-code-scanning.qls']);
t.deepEqual(resolveQueriesArgs[0].extraSearchPath, undefined);
t.assert(spyGetContents.called);
});
});
ava_1.default("API client used when reading remote config", async (t) => {
@@ -348,6 +330,8 @@ function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGen
return await util.withTmpDir(async (tmpDir) => {
process.env['RUNNER_TEMP'] = tmpDir;
process.env['GITHUB_WORKSPACE'] = tmpDir;
process.env['GITHUB_REPOSITORY'] = "octo-org/codeql-config";
process.env["GITHUB_REF"] = "refs/heads/main";
CodeQL.setCodeQL({
resolveQueries: async function () {
return {
@@ -357,8 +341,10 @@ function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGen
};
},
});
const inputFile = path.join(tmpDir, 'input');
fs.writeFileSync(inputFile, inputFileContents, 'utf8');
const dummyResponse = {
content: Buffer.from(inputFileContents).toString("base64"),
};
const spyGetContents = mockGetContents(dummyResponse);
setInput('config-file', 'input');
setInput('languages', 'javascript');
try {
@@ -366,7 +352,8 @@ function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGen
throw new Error('initConfig did not throw error');
}
catch (err) {
t.deepEqual(err, new Error(expectedErrorMessageGenerator(inputFile)));
t.deepEqual(err, new Error(expectedErrorMessageGenerator("input")));
t.assert(spyGetContents.called);
}
});
});
File diff suppressed because one or more lines are too long
+24 -39
View File
@@ -109,22 +109,6 @@ test("loading config saves config", async t => {
});
});
test("load input outside of workspace", async t => {
return await util.withTmpDir(async tmpDir => {
process.env['RUNNER_TEMP'] = tmpDir;
process.env['GITHUB_WORKSPACE'] = tmpDir;
setInput('config-file', '../input');
try {
await configUtils.initConfig();
throw new Error('initConfig did not throw error');
} catch (err) {
t.deepEqual(err, new Error(configUtils.getConfigFileOutsideWorkspaceErrorMessage(path.join(tmpDir, '../input'))));
}
});
});
test("load non-local input with invalid repo syntax", async t => {
return await util.withTmpDir(async tmpDir => {
process.env['RUNNER_TEMP'] = tmpDir;
@@ -142,28 +126,12 @@ test("load non-local input with invalid repo syntax", async t => {
});
});
test("load non-existent input", async t => {
return await util.withTmpDir(async tmpDir => {
process.env['RUNNER_TEMP'] = tmpDir;
process.env['GITHUB_WORKSPACE'] = tmpDir;
t.false(fs.existsSync(path.join(tmpDir, 'input')));
setInput('config-file', 'input');
setInput('languages', 'javascript');
try {
await configUtils.initConfig();
throw new Error('initConfig did not throw error');
} catch (err) {
t.deepEqual(err, new Error(configUtils.getConfigFileDoesNotExistErrorMessage(path.join(tmpDir, 'input'))));
}
});
});
test("load non-empty input", async t => {
return await util.withTmpDir(async tmpDir => {
process.env['RUNNER_TEMP'] = tmpDir;
process.env['GITHUB_WORKSPACE'] = tmpDir;
process.env['GITHUB_REPOSITORY'] = "octo-org/codeql-config";
process.env["GITHUB_REF"] = "refs/heads/main";
CodeQL.setCodeQL({
resolveQueries: async function() {
@@ -192,6 +160,11 @@ test("load non-empty input", async t => {
paths:
- c/d`;
const dummyResponse = {
content: Buffer.from(inputFileContents).toString("base64"),
};
const spyGetContents = mockGetContents(dummyResponse);
fs.mkdirSync(path.join(tmpDir, 'foo'));
// And the config we expect it to parse to
@@ -209,7 +182,6 @@ test("load non-empty input", async t => {
},
};
fs.writeFileSync(path.join(tmpDir, 'input'), inputFileContents, 'utf8');
setInput('config-file', 'input');
setInput('languages', 'javascript');
@@ -217,6 +189,7 @@ test("load non-empty input", async t => {
// Should exactly equal the object we constructed earlier
t.deepEqual(actualConfig, expectedConfig);
t.assert(spyGetContents.called);
});
});
@@ -224,6 +197,8 @@ test("default queries are used", async t => {
return await util.withTmpDir(async tmpDir => {
process.env['RUNNER_TEMP'] = tmpDir;
process.env['GITHUB_WORKSPACE'] = tmpDir;
process.env['GITHUB_REPOSITORY'] = "octo-org/codeql-config";
process.env["GITHUB_REF"] = "refs/heads/main";
// Check that the default behaviour is to add the default queries.
// In this case if a config file is specified but does not include
@@ -253,10 +228,13 @@ test("default queries are used", async t => {
const inputFileContents = `
paths:
- foo`;
const dummyResponse = {
content: Buffer.from(inputFileContents).toString("base64"),
};
const spyGetContents = mockGetContents(dummyResponse);
fs.mkdirSync(path.join(tmpDir, 'foo'));
fs.writeFileSync(path.join(tmpDir, 'input'), inputFileContents, 'utf8');
setInput('config-file', 'input');
setInput('languages', 'javascript');
@@ -266,6 +244,7 @@ test("default queries are used", async t => {
t.deepEqual(resolveQueriesArgs.length, 1);
t.deepEqual(resolveQueriesArgs[0].queries, ['javascript-code-scanning.qls']);
t.deepEqual(resolveQueriesArgs[0].extraSearchPath, undefined);
t.assert(spyGetContents.called);
});
});
@@ -397,6 +376,8 @@ function doInvalidInputTest(
return await util.withTmpDir(async tmpDir => {
process.env['RUNNER_TEMP'] = tmpDir;
process.env['GITHUB_WORKSPACE'] = tmpDir;
process.env['GITHUB_REPOSITORY'] = "octo-org/codeql-config";
process.env["GITHUB_REF"] = "refs/heads/main";
CodeQL.setCodeQL({
resolveQueries: async function() {
@@ -408,8 +389,11 @@ function doInvalidInputTest(
},
});
const inputFile = path.join(tmpDir, 'input');
fs.writeFileSync(inputFile, inputFileContents, 'utf8');
const dummyResponse = {
content: Buffer.from(inputFileContents).toString("base64"),
};
const spyGetContents = mockGetContents(dummyResponse);
setInput('config-file', 'input');
setInput('languages', 'javascript');
@@ -417,7 +401,8 @@ function doInvalidInputTest(
await configUtils.initConfig();
throw new Error('initConfig did not throw error');
} catch (err) {
t.deepEqual(err, new Error(expectedErrorMessageGenerator(inputFile)));
t.deepEqual(err, new Error(expectedErrorMessageGenerator("input")));
t.assert(spyGetContents.called);
}
});
});
+6 -26
View File
@@ -384,14 +384,6 @@ export function getLocalPathDoesNotExist(configFile: string, localPath: string):
'is invalid as the local path "' + localPath + '" does not exist in the repository');
}
export function getConfigFileOutsideWorkspaceErrorMessage(configFile: string): string {
return 'The configuration file "' + configFile + '" is outside of the workspace';
}
export function getConfigFileDoesNotExistErrorMessage(configFile: string): string {
return 'The configuration file "' + configFile + '" does not exist';
}
export function getConfigFileRepoFormatInvalidMessage(configFile: string): string {
let error = 'The configuration file "' + configFile + '" is not a supported remote file reference.';
error += ' Expected format <owner>/<repository>/<file-path>@<ref>';
@@ -543,11 +535,13 @@ async function loadConfig(configFile: string): Promise<Config> {
let parsedYAML: UserConfig;
if (isLocal(configFile)) {
// Treat the config file as relative to the workspace
const workspacePath = util.getRequiredEnvParam('GITHUB_WORKSPACE');
configFile = path.resolve(workspacePath, configFile);
// Even if its local we want to retrieve the config using the api.
parsedYAML = getLocalConfig(configFile, workspacePath);
// For using the api we have to remove the starting "./"
const configFilePath = configFile.substr(2);
const remote = util.getRequiredEnvParam("GITHUB_REPOSITORY") + "/" + configFilePath
+ "@" + util.getRef();
parsedYAML = await getRemoteConfig(remote);
} else {
parsedYAML = await getRemoteConfig(configFile);
}
@@ -666,20 +660,6 @@ function isLocal(configPath: string): boolean {
return (configPath.indexOf("@") === -1);
}
function getLocalConfig(configFile: string, workspacePath: string): UserConfig {
// Error if the config file is now outside of the workspace
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
throw new Error(getConfigFileOutsideWorkspaceErrorMessage(configFile));
}
// Error if the file does not exist
if (!fs.existsSync(configFile)) {
throw new Error(getConfigFileDoesNotExistErrorMessage(configFile));
}
return yaml.safeLoad(fs.readFileSync(configFile, 'utf8'));
}
async function getRemoteConfig(configFile: string): Promise<UserConfig> {
// retrieve the various parts of the config location, and ensure they're present
const format = new RegExp('(?<owner>[^/]+)/(?<repo>[^/]+)/(?<path>[^@]+)@(?<ref>.*)');