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

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;
);
}
/**

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,
},
);
});

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;
}
}

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 {