Add and use parseUserConfig

- Throws a `ConfigurationError` if parsing the YAML fails
- Add a couple of tests for it
This commit is contained in:
Michael B. Gale
2025-10-12 12:52:53 +01:00
parent 70205d3d12
commit 66df0bc515
5 changed files with 96 additions and 6 deletions
+19 -2
View File
@@ -85319,6 +85319,7 @@ function renamed(from, to) {
var load = loader.load;
var loadAll = loader.loadAll;
var dump = dumper.dump;
var YAMLException = exception;
var safeLoad = renamed("safeLoad", "load");
var safeLoadAll = renamed("safeLoadAll", "loadAll");
var safeDump = renamed("safeDump", "dump");
@@ -86310,6 +86311,9 @@ function getConfigFileOutsideWorkspaceErrorMessage(configFile) {
function getConfigFileDoesNotExistErrorMessage(configFile) {
return `The configuration file "${configFile}" does not exist`;
}
function getConfigFileParseErrorMessage(configFile, message) {
return `Cannot parse "${configFile}": ${message}`;
}
function getConfigFileRepoFormatInvalidMessage(configFile) {
let error2 = `The configuration file "${configFile}" is not a supported remote file reference.`;
error2 += " Expected format <owner>/<repository>/<file-path>@<ref>";
@@ -86601,6 +86605,18 @@ function generateCodeScanningConfig(logger, originalUserInput, augmentationPrope
}
return augmentedConfig;
}
function parseUserConfig(pathInput, contents) {
try {
return load(contents);
} catch (error2) {
if (error2 instanceof YAMLException) {
throw new ConfigurationError(
getConfigFileParseErrorMessage(pathInput, error2.message)
);
}
throw error2;
}
}
// src/feature-flags.ts
var fs7 = __toESM(require("fs"));
@@ -88033,7 +88049,7 @@ function getLocalConfig(configFile) {
getConfigFileDoesNotExistErrorMessage(configFile)
);
}
return load(fs9.readFileSync(configFile, "utf8"));
return parseUserConfig(configFile, fs9.readFileSync(configFile, "utf-8"));
}
async function getRemoteConfig(configFile, apiDetails) {
const format = new RegExp(
@@ -88063,7 +88079,8 @@ async function getRemoteConfig(configFile, apiDetails) {
getConfigFileFormatInvalidMessage(configFile)
);
}
return load(
return parseUserConfig(
configFile,
Buffer.from(fileContents, "base64").toString("binary")
);
}
+5 -3
View File
@@ -19,6 +19,7 @@ import {
calculateAugmentation,
ExcludeQueryFilter,
generateCodeScanningConfig,
parseUserConfig,
UserConfig,
} from "./config/db-config";
import { shouldPerformDiffInformedAnalysis } from "./diff-informed-analysis-utils";
@@ -905,7 +906,7 @@ function getLocalConfig(configFile: string): UserConfig {
);
}
return yaml.load(fs.readFileSync(configFile, "utf8")) as UserConfig;
return parseUserConfig(configFile, fs.readFileSync(configFile, "utf-8"));
}
async function getRemoteConfig(
@@ -946,9 +947,10 @@ async function getRemoteConfig(
);
}
return yaml.load(
return parseUserConfig(
configFile,
Buffer.from(fileContents, "base64").toString("binary"),
) as UserConfig;
);
}
/**
+40 -1
View File
@@ -2,7 +2,7 @@ import test, { ExecutionContext } from "ava";
import { RepositoryProperties } from "../feature-flags/properties";
import { KnownLanguage, Language } from "../languages";
import { prettyPrintPack } from "../util";
import { ConfigurationError, prettyPrintPack } from "../util";
import * as dbConfig from "./db-config";
@@ -391,3 +391,42 @@ test(
{},
/"a-pack-without-a-scope" is not a valid pack/,
);
test("parseUserConfig - successfully parses valid YAML", (t) => {
const result = dbConfig.parseUserConfig(
"test",
`
paths-ignore:
- "some/path"
queries:
- uses: foo
`,
);
t.truthy(result);
if (t.truthy(result["paths-ignore"])) {
t.is(result["paths-ignore"].length, 1);
t.is(result["paths-ignore"][0], "some/path");
}
if (t.truthy(result["queries"])) {
t.is(result["queries"].length, 1);
t.deepEqual(result["queries"][0], { uses: "foo" });
}
});
test("parseUserConfig - throws a ConfigurationError if the file is not valid YAML", (t) => {
t.throws(
() =>
dbConfig.parseUserConfig(
"test",
`
paths-ignore:
- "some/path"
queries:
- foo
`,
),
{
instanceOf: ConfigurationError,
},
);
});
+25
View File
@@ -1,5 +1,6 @@
import * as path from "path";
import * as yaml from "js-yaml";
import * as semver from "semver";
import * as errorMessages from "../error-messages";
@@ -474,3 +475,27 @@ export function generateCodeScanningConfig(
return augmentedConfig;
}
/**
* Attempts to parse `contents` into a `UserConfig` value.
*
* @param pathInput The path to the file where `contents` was obtained from, for use in error messages.
* @param contents The string contents of a YAML file to try and parse as a `UserConfig`.
* @returns The `UserConfig` corresponding to `contents`, if parsing was successful.
* @throws A `ConfigurationError` if parsing failed.
*/
export function parseUserConfig(
pathInput: string,
contents: string,
): UserConfig {
try {
return yaml.load(contents) as UserConfig;
} catch (error) {
if (error instanceof yaml.YAMLException) {
throw new ConfigurationError(
errorMessages.getConfigFileParseErrorMessage(pathInput, error.message),
);
}
throw error;
}
}
+7
View File
@@ -14,6 +14,13 @@ export function getConfigFileDoesNotExistErrorMessage(
return `The configuration file "${configFile}" does not exist`;
}
export function getConfigFileParseErrorMessage(
configFile: string,
message: string,
): string {
return `Cannot parse "${configFile}": ${message}`;
}
export function getConfigFileRepoFormatInvalidMessage(
configFile: string,
): string {