Add helper for substituting config variables
This commit is contained in:
57
extensions/ql-vscode/src/common/config-template.ts
Normal file
57
extensions/ql-vscode/src/common/config-template.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// Based on https://github.com/microsoft/vscode/blob/edfd5b8ba54d50f3f5c2ebee877af088803def88/src/vs/base/common/labels.ts#L316C1-L400
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to insert values for specific template variables into the string. E.g. "this ${is} a ${template}" can be
|
||||||
|
* passed to this function together with an object that maps "is" and "template" to strings to have them replaced.
|
||||||
|
*
|
||||||
|
* @param template string to which template is applied
|
||||||
|
* @param values the values of the templates to use
|
||||||
|
*/
|
||||||
|
export function substituteConfigVariables(
|
||||||
|
template: string,
|
||||||
|
values: {
|
||||||
|
[key: string]: string | undefined | null;
|
||||||
|
},
|
||||||
|
): string {
|
||||||
|
const segments: string[] = [];
|
||||||
|
|
||||||
|
let inVariable = false;
|
||||||
|
let currentValue = "";
|
||||||
|
for (const char of template) {
|
||||||
|
// Beginning of variable
|
||||||
|
if (char === "$" || (inVariable && char === "{")) {
|
||||||
|
if (currentValue) {
|
||||||
|
segments.push(currentValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentValue = "";
|
||||||
|
inVariable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End of variable
|
||||||
|
else if (char === "}" && inVariable) {
|
||||||
|
const resolved = values[currentValue];
|
||||||
|
|
||||||
|
// Variable
|
||||||
|
if (resolved && resolved.length > 0) {
|
||||||
|
segments.push(resolved);
|
||||||
|
}
|
||||||
|
// If the variable, doesn't exist, we discard it (i.e. replace it by the empty string)
|
||||||
|
|
||||||
|
currentValue = "";
|
||||||
|
inVariable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text or Variable Name
|
||||||
|
else {
|
||||||
|
currentValue += char;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tail
|
||||||
|
if (currentValue && !inVariable) {
|
||||||
|
segments.push(currentValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return segments.join("");
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import { substituteConfigVariables } from "../../../src/common/config-template";
|
||||||
|
|
||||||
|
describe("substituteConfigVariables", () => {
|
||||||
|
const values = {
|
||||||
|
userHome: "/home/your-username",
|
||||||
|
workspaceFolder: "/home/your-username/your-project",
|
||||||
|
workspaceFolderBasename: "your-project",
|
||||||
|
pathSeparator: "/",
|
||||||
|
owner: "github",
|
||||||
|
name: "vscode-codeql",
|
||||||
|
language: "java",
|
||||||
|
};
|
||||||
|
|
||||||
|
const testCases = [
|
||||||
|
{
|
||||||
|
template: ".github/codeql/extensions/${name}-${language}",
|
||||||
|
expected: ".github/codeql/extensions/vscode-codeql-java",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "${owner}/${name}-${language}",
|
||||||
|
expected: "github/vscode-codeql-java",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "models/${group}.model.yml",
|
||||||
|
expected: "models/.model.yml",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template:
|
||||||
|
"${workspaceFolder}${pathSeparator}.github/workflows/codeql-analysis.yml",
|
||||||
|
expected:
|
||||||
|
"/home/your-username/your-project/.github/workflows/codeql-analysis.yml",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template:
|
||||||
|
"${workspaceFolder/.github/codeql/extensions/${name}-${language}",
|
||||||
|
expected: "workspaceFolder/.github/codeql/extensions/vscode-codeql-java",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "}${workspaceFolder}/.github/workflows/codeql-analysis.yml",
|
||||||
|
expected:
|
||||||
|
"}/home/your-username/your-project/.github/workflows/codeql-analysis.yml",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "Foo Bar",
|
||||||
|
expected: "Foo Bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "Foo${}Bar",
|
||||||
|
expected: "FooBar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "$FooBar",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "}FooBar",
|
||||||
|
expected: "}FooBar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "Foo ${name} Bar",
|
||||||
|
expected: "Foo vscode-codeql Bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "Foo ${name} Bar ${owner}",
|
||||||
|
expected: "Foo vscode-codeql Bar github",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: "Foo ${nmae} Bar ${owner}",
|
||||||
|
expected: "Foo Bar github",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
test.each(testCases)(
|
||||||
|
"result of $template is $expected",
|
||||||
|
({ template, expected }) => {
|
||||||
|
expect(substituteConfigVariables(template, values)).toEqual(expected);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user