Merge pull request #2345 from github/koesie10/filter-extension-packs-for-language
Filter extension packs by database item language
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
import { ProgressCallback } from "../progress";
|
||||
import { DatabaseItem } from "../local-databases";
|
||||
import { getQlPackPath, QLPACK_FILENAMES } from "../pure/ql";
|
||||
import { getErrorMessage } from "../pure/helpers-pure";
|
||||
|
||||
const maxStep = 3;
|
||||
|
||||
@@ -22,8 +23,14 @@ const packNameRegex = new RegExp(
|
||||
const packNameLength = 128;
|
||||
|
||||
export interface ExtensionPack {
|
||||
name: string;
|
||||
path: string;
|
||||
yamlPath: string;
|
||||
|
||||
name: string;
|
||||
version: string;
|
||||
|
||||
extensionTargets: Record<string, string>;
|
||||
dataExtensions: string[];
|
||||
}
|
||||
|
||||
export interface ExtensionPackModelFile {
|
||||
@@ -50,7 +57,7 @@ export async function pickExtensionPackModelFile(
|
||||
const modelFile = await pickModelFile(
|
||||
cliServer,
|
||||
databaseItem,
|
||||
extensionPack.path,
|
||||
extensionPack,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
@@ -78,19 +85,72 @@ async function pickExtensionPack(
|
||||
|
||||
// Get all existing extension packs in the workspace
|
||||
const additionalPacks = getOnDiskWorkspaceFolders();
|
||||
const extensionPacks = await cliServer.resolveQlpacks(additionalPacks, true);
|
||||
const extensionPacksInfo = await cliServer.resolveQlpacks(
|
||||
additionalPacks,
|
||||
true,
|
||||
);
|
||||
|
||||
if (Object.keys(extensionPacks).length === 0) {
|
||||
if (Object.keys(extensionPacksInfo).length === 0) {
|
||||
return pickNewExtensionPack(databaseItem, token);
|
||||
}
|
||||
|
||||
const options: Array<{ label: string; extensionPack: string | null }> =
|
||||
Object.keys(extensionPacks).map((pack) => ({
|
||||
label: pack,
|
||||
extensionPack: pack,
|
||||
}));
|
||||
const extensionPacks = (
|
||||
await Promise.all(
|
||||
Object.entries(extensionPacksInfo).map(async ([name, paths]) => {
|
||||
if (paths.length !== 1) {
|
||||
void showAndLogErrorMessage(
|
||||
`Extension pack ${name} resolves to multiple paths`,
|
||||
{
|
||||
fullMessage: `Extension pack ${name} resolves to multiple paths: ${paths.join(
|
||||
", ",
|
||||
)}`,
|
||||
},
|
||||
);
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const path = paths[0];
|
||||
|
||||
let extensionPack: ExtensionPack;
|
||||
try {
|
||||
extensionPack = await readExtensionPack(path);
|
||||
} catch (e: unknown) {
|
||||
void showAndLogErrorMessage(`Could not read extension pack ${name}`, {
|
||||
fullMessage: `Could not read extension pack ${name} at ${path}: ${getErrorMessage(
|
||||
e,
|
||||
)}`,
|
||||
});
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return extensionPack;
|
||||
}),
|
||||
)
|
||||
).filter((info): info is ExtensionPack => info !== undefined);
|
||||
|
||||
const extensionPacksForLanguage = extensionPacks.filter(
|
||||
(pack) =>
|
||||
pack.extensionTargets[`codeql/${databaseItem.language}-all`] !==
|
||||
undefined,
|
||||
);
|
||||
|
||||
const options: Array<{
|
||||
label: string;
|
||||
description: string | undefined;
|
||||
detail: string | undefined;
|
||||
extensionPack: ExtensionPack | null;
|
||||
}> = extensionPacksForLanguage.map((pack) => ({
|
||||
label: pack.name,
|
||||
description: pack.version,
|
||||
detail: pack.path,
|
||||
extensionPack: pack,
|
||||
}));
|
||||
options.push({
|
||||
label: "Create new extension pack",
|
||||
description: undefined,
|
||||
detail: undefined,
|
||||
extensionPack: null,
|
||||
});
|
||||
|
||||
@@ -115,57 +175,39 @@ async function pickExtensionPack(
|
||||
return pickNewExtensionPack(databaseItem, token);
|
||||
}
|
||||
|
||||
const extensionPackPaths = extensionPacks[extensionPackOption.extensionPack];
|
||||
if (extensionPackPaths.length !== 1) {
|
||||
void showAndLogErrorMessage(
|
||||
`Extension pack ${extensionPackOption.extensionPack} could not be resolved to a single location`,
|
||||
{
|
||||
fullMessage: `Extension pack ${
|
||||
extensionPackOption.extensionPack
|
||||
} could not be resolved to a single location. Found ${
|
||||
extensionPackPaths.length
|
||||
} locations: ${extensionPackPaths.join(", ")}.`,
|
||||
},
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
name: extensionPackOption.extensionPack,
|
||||
path: extensionPackPaths[0],
|
||||
};
|
||||
return extensionPackOption.extensionPack;
|
||||
}
|
||||
|
||||
async function pickModelFile(
|
||||
cliServer: Pick<CodeQLCliServer, "resolveExtensions">,
|
||||
databaseItem: Pick<DatabaseItem, "name">,
|
||||
extensionPackPath: string,
|
||||
extensionPack: ExtensionPack,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
): Promise<string | undefined> {
|
||||
// Find the existing model files in the extension pack
|
||||
const additionalPacks = getOnDiskWorkspaceFolders();
|
||||
const extensions = await cliServer.resolveExtensions(
|
||||
extensionPackPath,
|
||||
extensionPack.path,
|
||||
additionalPacks,
|
||||
);
|
||||
|
||||
const modelFiles = new Set<string>();
|
||||
|
||||
if (extensionPackPath in extensions.data) {
|
||||
for (const extension of extensions.data[extensionPackPath]) {
|
||||
if (extensionPack.path in extensions.data) {
|
||||
for (const extension of extensions.data[extensionPack.path]) {
|
||||
modelFiles.add(extension.file);
|
||||
}
|
||||
}
|
||||
|
||||
if (modelFiles.size === 0) {
|
||||
return pickNewModelFile(databaseItem, extensionPackPath, token);
|
||||
return pickNewModelFile(databaseItem, extensionPack, token);
|
||||
}
|
||||
|
||||
const fileOptions: Array<{ label: string; file: string | null }> = [];
|
||||
for (const file of modelFiles) {
|
||||
fileOptions.push({
|
||||
label: relative(extensionPackPath, file).replaceAll(sep, "/"),
|
||||
label: relative(extensionPack.path, file).replaceAll(sep, "/"),
|
||||
file,
|
||||
});
|
||||
}
|
||||
@@ -196,7 +238,7 @@ async function pickModelFile(
|
||||
return fileOption.file;
|
||||
}
|
||||
|
||||
return pickNewModelFile(databaseItem, extensionPackPath, token);
|
||||
return pickNewModelFile(databaseItem, extensionPack, token);
|
||||
}
|
||||
|
||||
async function pickNewExtensionPack(
|
||||
@@ -266,66 +308,36 @@ async function pickNewExtensionPack(
|
||||
|
||||
const packYamlPath = join(packPath, "codeql-pack.yml");
|
||||
|
||||
const extensionPack: ExtensionPack = {
|
||||
path: packPath,
|
||||
yamlPath: packYamlPath,
|
||||
name,
|
||||
version: "0.0.0",
|
||||
extensionTargets: {
|
||||
[`codeql/${databaseItem.language}-all`]: "*",
|
||||
},
|
||||
dataExtensions: ["models/**/*.yml"],
|
||||
};
|
||||
|
||||
await outputFile(
|
||||
packYamlPath,
|
||||
dumpYaml({
|
||||
name,
|
||||
version: "0.0.0",
|
||||
name: extensionPack.name,
|
||||
version: extensionPack.version,
|
||||
library: true,
|
||||
extensionTargets: {
|
||||
[`codeql/${databaseItem.language}-all`]: "*",
|
||||
},
|
||||
dataExtensions: ["models/**/*.yml"],
|
||||
extensionTargets: extensionPack.extensionTargets,
|
||||
dataExtensions: extensionPack.dataExtensions,
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
name: packName,
|
||||
path: packPath,
|
||||
};
|
||||
return extensionPack;
|
||||
}
|
||||
|
||||
async function pickNewModelFile(
|
||||
databaseItem: Pick<DatabaseItem, "name">,
|
||||
extensionPackPath: string,
|
||||
extensionPack: ExtensionPack,
|
||||
token: CancellationToken,
|
||||
) {
|
||||
const qlpackPath = await getQlPackPath(extensionPackPath);
|
||||
if (!qlpackPath) {
|
||||
void showAndLogErrorMessage(
|
||||
`Could not find any of ${QLPACK_FILENAMES.join(
|
||||
", ",
|
||||
)} in ${extensionPackPath}`,
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const qlpack = await loadYaml(await readFile(qlpackPath, "utf8"), {
|
||||
filename: qlpackPath,
|
||||
});
|
||||
if (typeof qlpack !== "object" || qlpack === null) {
|
||||
void showAndLogErrorMessage(`Could not parse ${qlpackPath}`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const dataExtensionPatternsValue = qlpack.dataExtensions;
|
||||
if (
|
||||
!(
|
||||
Array.isArray(dataExtensionPatternsValue) ||
|
||||
typeof dataExtensionPatternsValue === "string"
|
||||
)
|
||||
) {
|
||||
void showAndLogErrorMessage(
|
||||
`Expected 'dataExtensions' to be a string or an array in ${qlpackPath}`,
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// The YAML allows either a string or an array of strings
|
||||
const dataExtensionPatterns = Array.isArray(dataExtensionPatternsValue)
|
||||
? dataExtensionPatternsValue
|
||||
: [dataExtensionPatternsValue];
|
||||
|
||||
const filename = await window.showInputBox(
|
||||
{
|
||||
title: "Enter the name of the new model file",
|
||||
@@ -335,24 +347,25 @@ async function pickNewModelFile(
|
||||
return "File name must not be empty";
|
||||
}
|
||||
|
||||
const path = resolve(extensionPackPath, value);
|
||||
const path = resolve(extensionPack.path, value);
|
||||
|
||||
if (await pathExists(path)) {
|
||||
return "File already exists";
|
||||
}
|
||||
|
||||
const notInExtensionPack = relative(extensionPackPath, path).startsWith(
|
||||
"..",
|
||||
);
|
||||
const notInExtensionPack = relative(
|
||||
extensionPack.path,
|
||||
path,
|
||||
).startsWith("..");
|
||||
if (notInExtensionPack) {
|
||||
return "File must be in the extension pack";
|
||||
}
|
||||
|
||||
const matchesPattern = dataExtensionPatterns.some((pattern) =>
|
||||
const matchesPattern = extensionPack.dataExtensions.some((pattern) =>
|
||||
minimatch(value, pattern, { matchBase: true }),
|
||||
);
|
||||
if (!matchesPattern) {
|
||||
return `File must match one of the patterns in 'dataExtensions' in ${qlpackPath}`;
|
||||
return `File must match one of the patterns in 'dataExtensions' in ${extensionPack.yamlPath}`;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -364,5 +377,47 @@ async function pickNewModelFile(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return resolve(extensionPackPath, filename);
|
||||
return resolve(extensionPack.path, filename);
|
||||
}
|
||||
|
||||
async function readExtensionPack(path: string): Promise<ExtensionPack> {
|
||||
const qlpackPath = await getQlPackPath(path);
|
||||
if (!qlpackPath) {
|
||||
throw new Error(
|
||||
`Could not find any of ${QLPACK_FILENAMES.join(", ")} in ${path}`,
|
||||
);
|
||||
}
|
||||
|
||||
const qlpack = await loadYaml(await readFile(qlpackPath, "utf8"), {
|
||||
filename: qlpackPath,
|
||||
});
|
||||
if (typeof qlpack !== "object" || qlpack === null) {
|
||||
throw new Error(`Could not parse ${qlpackPath}`);
|
||||
}
|
||||
|
||||
const dataExtensionValue = qlpack.dataExtensions;
|
||||
if (
|
||||
!(
|
||||
Array.isArray(dataExtensionValue) ||
|
||||
typeof dataExtensionValue === "string"
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
`Expected 'dataExtensions' to be a string or an array in ${qlpackPath}`,
|
||||
);
|
||||
}
|
||||
|
||||
// The YAML allows either a string or an array of strings
|
||||
const dataExtensions = Array.isArray(dataExtensionValue)
|
||||
? dataExtensionValue
|
||||
: [dataExtensionValue];
|
||||
|
||||
return {
|
||||
path,
|
||||
yamlPath: qlpackPath,
|
||||
name: qlpack.name,
|
||||
version: qlpack.version,
|
||||
extensionTargets: qlpack.extensionTargets,
|
||||
dataExtensions,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,28 +3,23 @@ import { dump as dumpYaml, load as loadYaml } from "js-yaml";
|
||||
import { outputFile, readFile } from "fs-extra";
|
||||
import { join } from "path";
|
||||
import { dir } from "tmp-promise";
|
||||
|
||||
import { pickExtensionPackModelFile } from "../../../../src/data-extensions-editor/extension-pack-picker";
|
||||
import { QlpacksInfo, ResolveExtensionsResult } from "../../../../src/cli";
|
||||
import * as helpers from "../../../../src/helpers";
|
||||
|
||||
import {
|
||||
ExtensionPack,
|
||||
pickExtensionPackModelFile,
|
||||
} from "../../../../src/data-extensions-editor/extension-pack-picker";
|
||||
|
||||
describe("pickExtensionPackModelFile", () => {
|
||||
const qlPacks = {
|
||||
"my-extension-pack": ["/a/b/c/my-extension-pack"],
|
||||
"another-extension-pack": ["/a/b/c/another-extension-pack"],
|
||||
};
|
||||
const extensions = {
|
||||
models: [],
|
||||
data: {
|
||||
"/a/b/c/my-extension-pack": [
|
||||
{
|
||||
file: "/a/b/c/my-extension-pack/models/model.yml",
|
||||
index: 0,
|
||||
predicate: "sinkModel",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
let tmpDir: string;
|
||||
let extensionPackPath: string;
|
||||
let anotherExtensionPackPath: string;
|
||||
let extensionPack: ExtensionPack;
|
||||
let anotherExtensionPack: ExtensionPack;
|
||||
|
||||
let qlPacks: QlpacksInfo;
|
||||
let extensions: ResolveExtensionsResult;
|
||||
const databaseItem = {
|
||||
name: "github/vscode-codeql",
|
||||
language: "java",
|
||||
@@ -40,7 +35,42 @@ describe("pickExtensionPackModelFile", () => {
|
||||
typeof helpers.showAndLogErrorMessage
|
||||
>;
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(async () => {
|
||||
tmpDir = (
|
||||
await dir({
|
||||
unsafeCleanup: true,
|
||||
})
|
||||
).path;
|
||||
|
||||
extensionPackPath = join(tmpDir, "my-extension-pack");
|
||||
anotherExtensionPackPath = join(tmpDir, "another-extension-pack");
|
||||
|
||||
qlPacks = {
|
||||
"my-extension-pack": [extensionPackPath],
|
||||
"another-extension-pack": [anotherExtensionPackPath],
|
||||
};
|
||||
extensions = {
|
||||
models: [],
|
||||
data: {
|
||||
[extensionPackPath]: [
|
||||
{
|
||||
file: join(extensionPackPath, "models", "model.yml"),
|
||||
index: 0,
|
||||
predicate: "sinkModel",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
extensionPack = await createMockExtensionPack(
|
||||
extensionPackPath,
|
||||
"my-extension-pack",
|
||||
);
|
||||
anotherExtensionPack = await createMockExtensionPack(
|
||||
anotherExtensionPackPath,
|
||||
"another-extension-pack",
|
||||
);
|
||||
|
||||
showQuickPickSpy = jest
|
||||
.spyOn(window, "showQuickPick")
|
||||
.mockRejectedValue(new Error("Unexpected call to showQuickPick"));
|
||||
@@ -55,15 +85,17 @@ describe("pickExtensionPackModelFile", () => {
|
||||
});
|
||||
|
||||
it("allows choosing an existing extension pack and model file", async () => {
|
||||
const modelPath = join(extensionPackPath, "models", "model.yml");
|
||||
|
||||
const cliServer = mockCliServer(qlPacks, extensions);
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
extensionPack,
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "models/model.yml",
|
||||
file: "/a/b/c/my-extension-pack/models/model.yml",
|
||||
file: modelPath,
|
||||
} as QuickPickItem);
|
||||
|
||||
expect(
|
||||
@@ -74,22 +106,23 @@ describe("pickExtensionPackModelFile", () => {
|
||||
token,
|
||||
),
|
||||
).toEqual({
|
||||
filename: "/a/b/c/my-extension-pack/models/model.yml",
|
||||
extensionPack: {
|
||||
name: "my-extension-pack",
|
||||
path: "/a/b/c/my-extension-pack",
|
||||
},
|
||||
filename: modelPath,
|
||||
extensionPack,
|
||||
});
|
||||
expect(showQuickPickSpy).toHaveBeenCalledTimes(2);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledWith(
|
||||
[
|
||||
{
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
description: "0.0.0",
|
||||
detail: extensionPackPath,
|
||||
extensionPack,
|
||||
},
|
||||
{
|
||||
label: "another-extension-pack",
|
||||
extensionPack: "another-extension-pack",
|
||||
description: "0.0.0",
|
||||
detail: anotherExtensionPackPath,
|
||||
extensionPack: anotherExtensionPack,
|
||||
},
|
||||
{
|
||||
label: expect.stringMatching(/create/i),
|
||||
@@ -105,7 +138,7 @@ describe("pickExtensionPackModelFile", () => {
|
||||
[
|
||||
{
|
||||
label: "models/model.yml",
|
||||
file: "/a/b/c/my-extension-pack/models/model.yml",
|
||||
file: modelPath,
|
||||
},
|
||||
{
|
||||
label: expect.stringMatching(/create/i),
|
||||
@@ -121,38 +154,17 @@ describe("pickExtensionPackModelFile", () => {
|
||||
expect(cliServer.resolveQlpacks).toHaveBeenCalledWith([], true);
|
||||
expect(cliServer.resolveExtensions).toHaveBeenCalledTimes(1);
|
||||
expect(cliServer.resolveExtensions).toHaveBeenCalledWith(
|
||||
"/a/b/c/my-extension-pack",
|
||||
extensionPackPath,
|
||||
[],
|
||||
);
|
||||
});
|
||||
|
||||
it("allows choosing an existing extension pack and creating a new model file", async () => {
|
||||
const tmpDir = await dir({
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
const cliServer = mockCliServer(
|
||||
{
|
||||
...qlPacks,
|
||||
"my-extension-pack": [tmpDir.path],
|
||||
},
|
||||
{
|
||||
models: extensions.models,
|
||||
data: {
|
||||
[tmpDir.path]: [
|
||||
{
|
||||
file: join(tmpDir.path, "models/model.yml"),
|
||||
index: 0,
|
||||
predicate: "sinkModel",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
);
|
||||
const cliServer = mockCliServer(qlPacks, extensions);
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
extensionPack,
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "create",
|
||||
@@ -160,19 +172,6 @@ describe("pickExtensionPackModelFile", () => {
|
||||
} as QuickPickItem);
|
||||
showInputBoxSpy.mockResolvedValue("models/my-model.yml");
|
||||
|
||||
await outputFile(
|
||||
join(tmpDir.path, "codeql-pack.yml"),
|
||||
dumpYaml({
|
||||
name: "my-extension-pack",
|
||||
version: "0.0.0",
|
||||
library: true,
|
||||
extensionTargets: {
|
||||
"codeql/java-all": "*",
|
||||
},
|
||||
dataExtensions: ["models/**/*.yml"],
|
||||
}),
|
||||
);
|
||||
|
||||
expect(
|
||||
await pickExtensionPackModelFile(
|
||||
cliServer,
|
||||
@@ -181,49 +180,10 @@ describe("pickExtensionPackModelFile", () => {
|
||||
token,
|
||||
),
|
||||
).toEqual({
|
||||
filename: join(tmpDir.path, "models/my-model.yml"),
|
||||
extensionPack: {
|
||||
name: "my-extension-pack",
|
||||
path: tmpDir.path,
|
||||
},
|
||||
filename: join(extensionPackPath, "models", "my-model.yml"),
|
||||
extensionPack,
|
||||
});
|
||||
expect(showQuickPickSpy).toHaveBeenCalledTimes(2);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledWith(
|
||||
[
|
||||
{
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
},
|
||||
{
|
||||
label: "another-extension-pack",
|
||||
extensionPack: "another-extension-pack",
|
||||
},
|
||||
{
|
||||
label: expect.stringMatching(/create/i),
|
||||
extensionPack: null,
|
||||
},
|
||||
],
|
||||
{
|
||||
title: expect.any(String),
|
||||
},
|
||||
token,
|
||||
);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledWith(
|
||||
[
|
||||
{
|
||||
label: "models/model.yml",
|
||||
file: join(tmpDir.path, "models/model.yml"),
|
||||
},
|
||||
{
|
||||
label: expect.stringMatching(/create/i),
|
||||
file: null,
|
||||
},
|
||||
],
|
||||
{
|
||||
title: expect.any(String),
|
||||
},
|
||||
token,
|
||||
);
|
||||
expect(showInputBoxSpy).toHaveBeenCalledWith(
|
||||
{
|
||||
title: expect.any(String),
|
||||
@@ -235,7 +195,10 @@ describe("pickExtensionPackModelFile", () => {
|
||||
expect(cliServer.resolveQlpacks).toHaveBeenCalledTimes(1);
|
||||
expect(cliServer.resolveQlpacks).toHaveBeenCalledWith([], true);
|
||||
expect(cliServer.resolveExtensions).toHaveBeenCalledTimes(1);
|
||||
expect(cliServer.resolveExtensions).toHaveBeenCalledWith(tmpDir.path, []);
|
||||
expect(cliServer.resolveExtensions).toHaveBeenCalledWith(
|
||||
extensionPackPath,
|
||||
[],
|
||||
);
|
||||
});
|
||||
|
||||
it("allows cancelling the extension pack prompt", async () => {
|
||||
@@ -262,11 +225,13 @@ describe("pickExtensionPackModelFile", () => {
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
const newPackDir = join(tmpDir.path, "new-extension-pack");
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "codeql-custom-queries-java",
|
||||
path: tmpDir.path,
|
||||
} as QuickPickItem);
|
||||
showInputBoxSpy.mockResolvedValueOnce("my-extension-pack");
|
||||
showInputBoxSpy.mockResolvedValueOnce("new-extension-pack");
|
||||
showInputBoxSpy.mockResolvedValue("models/my-model.yml");
|
||||
|
||||
expect(
|
||||
@@ -277,15 +242,16 @@ describe("pickExtensionPackModelFile", () => {
|
||||
token,
|
||||
),
|
||||
).toEqual({
|
||||
filename: join(
|
||||
tmpDir.path,
|
||||
"my-extension-pack",
|
||||
"models",
|
||||
"my-model.yml",
|
||||
),
|
||||
filename: join(newPackDir, "models", "my-model.yml"),
|
||||
extensionPack: {
|
||||
name: "my-extension-pack",
|
||||
path: join(tmpDir.path, "my-extension-pack"),
|
||||
path: newPackDir,
|
||||
yamlPath: join(newPackDir, "codeql-pack.yml"),
|
||||
name: "new-extension-pack",
|
||||
version: "0.0.0",
|
||||
extensionTargets: {
|
||||
"codeql/java-all": "*",
|
||||
},
|
||||
dataExtensions: ["models/**/*.yml"],
|
||||
},
|
||||
});
|
||||
expect(showQuickPickSpy).toHaveBeenCalledTimes(1);
|
||||
@@ -311,14 +277,9 @@ describe("pickExtensionPackModelFile", () => {
|
||||
expect(cliServer.resolveExtensions).toHaveBeenCalled();
|
||||
|
||||
expect(
|
||||
loadYaml(
|
||||
await readFile(
|
||||
join(tmpDir.path, "my-extension-pack", "codeql-pack.yml"),
|
||||
"utf8",
|
||||
),
|
||||
),
|
||||
loadYaml(await readFile(join(newPackDir, "codeql-pack.yml"), "utf8")),
|
||||
).toEqual({
|
||||
name: "my-extension-pack",
|
||||
name: "new-extension-pack",
|
||||
version: "0.0.0",
|
||||
library: true,
|
||||
extensionTargets: {
|
||||
@@ -335,11 +296,13 @@ describe("pickExtensionPackModelFile", () => {
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
const newPackDir = join(tmpDir.path, "new-extension-pack");
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "codeql-custom-queries-java",
|
||||
path: tmpDir.path,
|
||||
} as QuickPickItem);
|
||||
showInputBoxSpy.mockResolvedValueOnce("my-extension-pack");
|
||||
showInputBoxSpy.mockResolvedValueOnce("new-extension-pack");
|
||||
showInputBoxSpy.mockResolvedValue("models/my-model.yml");
|
||||
|
||||
expect(
|
||||
@@ -353,15 +316,16 @@ describe("pickExtensionPackModelFile", () => {
|
||||
token,
|
||||
),
|
||||
).toEqual({
|
||||
filename: join(
|
||||
tmpDir.path,
|
||||
"my-extension-pack",
|
||||
"models",
|
||||
"my-model.yml",
|
||||
),
|
||||
filename: join(newPackDir, "models", "my-model.yml"),
|
||||
extensionPack: {
|
||||
name: "my-extension-pack",
|
||||
path: join(tmpDir.path, "my-extension-pack"),
|
||||
path: newPackDir,
|
||||
yamlPath: join(newPackDir, "codeql-pack.yml"),
|
||||
name: "new-extension-pack",
|
||||
version: "0.0.0",
|
||||
extensionTargets: {
|
||||
"codeql/csharp-all": "*",
|
||||
},
|
||||
dataExtensions: ["models/**/*.yml"],
|
||||
},
|
||||
});
|
||||
expect(showQuickPickSpy).toHaveBeenCalledTimes(1);
|
||||
@@ -387,14 +351,9 @@ describe("pickExtensionPackModelFile", () => {
|
||||
expect(cliServer.resolveExtensions).toHaveBeenCalled();
|
||||
|
||||
expect(
|
||||
loadYaml(
|
||||
await readFile(
|
||||
join(tmpDir.path, "my-extension-pack", "codeql-pack.yml"),
|
||||
"utf8",
|
||||
),
|
||||
),
|
||||
loadYaml(await readFile(join(newPackDir, "codeql-pack.yml"), "utf8")),
|
||||
).toEqual({
|
||||
name: "my-extension-pack",
|
||||
name: "new-extension-pack",
|
||||
version: "0.0.0",
|
||||
library: true,
|
||||
extensionTargets: {
|
||||
@@ -459,10 +418,7 @@ describe("pickExtensionPackModelFile", () => {
|
||||
{ models: [], data: {} },
|
||||
);
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce(undefined);
|
||||
|
||||
expect(
|
||||
await pickExtensionPackModelFile(
|
||||
@@ -474,10 +430,22 @@ describe("pickExtensionPackModelFile", () => {
|
||||
).toEqual(undefined);
|
||||
expect(showAndLogErrorMessageSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showAndLogErrorMessageSpy).toHaveBeenCalledWith(
|
||||
expect.stringMatching(/could not be resolved to a single location/),
|
||||
expect.stringMatching(/resolves to multiple paths/),
|
||||
expect.anything(),
|
||||
);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledWith(
|
||||
[
|
||||
{
|
||||
label: expect.stringMatching(/create/i),
|
||||
extensionPack: null,
|
||||
},
|
||||
],
|
||||
{
|
||||
title: "Select extension pack to use",
|
||||
},
|
||||
token,
|
||||
);
|
||||
expect(cliServer.resolveQlpacks).toHaveBeenCalled();
|
||||
expect(cliServer.resolveExtensions).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -487,7 +455,7 @@ describe("pickExtensionPackModelFile", () => {
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
extensionPack,
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce(undefined);
|
||||
|
||||
@@ -508,29 +476,21 @@ describe("pickExtensionPackModelFile", () => {
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
const extensionPack = await createMockExtensionPack(
|
||||
tmpDir.path,
|
||||
"no-extension-pack",
|
||||
);
|
||||
|
||||
const cliServer = mockCliServer(
|
||||
{
|
||||
"my-extension-pack": [tmpDir.path],
|
||||
"no-extension-pack": [tmpDir.path],
|
||||
},
|
||||
{ models: [], data: {} },
|
||||
);
|
||||
|
||||
await outputFile(
|
||||
join(tmpDir.path, "codeql-pack.yml"),
|
||||
dumpYaml({
|
||||
name: "my-extension-pack",
|
||||
version: "0.0.0",
|
||||
library: true,
|
||||
extensionTargets: {
|
||||
"codeql/java-all": "*",
|
||||
},
|
||||
dataExtensions: ["models/**/*.yml"],
|
||||
}),
|
||||
);
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
label: "no-extension-pack",
|
||||
extensionPack,
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce(undefined);
|
||||
showInputBoxSpy.mockResolvedValue("models/my-model.yml");
|
||||
@@ -544,10 +504,7 @@ describe("pickExtensionPackModelFile", () => {
|
||||
),
|
||||
).toEqual({
|
||||
filename: join(tmpDir.path, "models", "my-model.yml"),
|
||||
extensionPack: {
|
||||
name: "my-extension-pack",
|
||||
path: tmpDir.path,
|
||||
},
|
||||
extensionPack,
|
||||
});
|
||||
expect(showQuickPickSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showInputBoxSpy).toHaveBeenCalledWith(
|
||||
@@ -574,10 +531,6 @@ describe("pickExtensionPackModelFile", () => {
|
||||
{ models: [], data: {} },
|
||||
);
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce(undefined);
|
||||
showAndLogErrorMessageSpy.mockResolvedValue(undefined);
|
||||
|
||||
@@ -590,13 +543,26 @@ describe("pickExtensionPackModelFile", () => {
|
||||
),
|
||||
).toEqual(undefined);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledWith(
|
||||
[
|
||||
{
|
||||
label: expect.stringMatching(/create/i),
|
||||
extensionPack: null,
|
||||
},
|
||||
],
|
||||
{
|
||||
title: "Select extension pack to use",
|
||||
},
|
||||
token,
|
||||
);
|
||||
expect(showInputBoxSpy).not.toHaveBeenCalled();
|
||||
expect(showAndLogErrorMessageSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showAndLogErrorMessageSpy).toHaveBeenCalledWith(
|
||||
expect.stringMatching(/codeql-pack\.yml/),
|
||||
expect.stringMatching(/my-extension-pack/),
|
||||
expect.anything(),
|
||||
);
|
||||
expect(cliServer.resolveQlpacks).toHaveBeenCalled();
|
||||
expect(cliServer.resolveExtensions).toHaveBeenCalled();
|
||||
expect(cliServer.resolveExtensions).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("shows an error when the pack YAML file is invalid", async () => {
|
||||
@@ -613,10 +579,6 @@ describe("pickExtensionPackModelFile", () => {
|
||||
|
||||
await outputFile(join(tmpDir.path, "codeql-pack.yml"), dumpYaml("java"));
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce(undefined);
|
||||
showAndLogErrorMessageSpy.mockResolvedValue(undefined);
|
||||
|
||||
@@ -629,13 +591,26 @@ describe("pickExtensionPackModelFile", () => {
|
||||
),
|
||||
).toEqual(undefined);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledWith(
|
||||
[
|
||||
{
|
||||
label: expect.stringMatching(/create/i),
|
||||
extensionPack: null,
|
||||
},
|
||||
],
|
||||
{
|
||||
title: "Select extension pack to use",
|
||||
},
|
||||
token,
|
||||
);
|
||||
expect(showInputBoxSpy).not.toHaveBeenCalled();
|
||||
expect(showAndLogErrorMessageSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showAndLogErrorMessageSpy).toHaveBeenCalledWith(
|
||||
expect.stringMatching(/Could not parse/),
|
||||
expect.stringMatching(/my-extension-pack/),
|
||||
expect.anything(),
|
||||
);
|
||||
expect(cliServer.resolveQlpacks).toHaveBeenCalled();
|
||||
expect(cliServer.resolveExtensions).toHaveBeenCalled();
|
||||
expect(cliServer.resolveExtensions).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("shows an error when the pack YAML does not contain dataExtensions", async () => {
|
||||
@@ -662,10 +637,6 @@ describe("pickExtensionPackModelFile", () => {
|
||||
}),
|
||||
);
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce(undefined);
|
||||
showAndLogErrorMessageSpy.mockResolvedValue(undefined);
|
||||
|
||||
@@ -678,13 +649,26 @@ describe("pickExtensionPackModelFile", () => {
|
||||
),
|
||||
).toEqual(undefined);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledWith(
|
||||
[
|
||||
{
|
||||
label: expect.stringMatching(/create/i),
|
||||
extensionPack: null,
|
||||
},
|
||||
],
|
||||
{
|
||||
title: "Select extension pack to use",
|
||||
},
|
||||
token,
|
||||
);
|
||||
expect(showInputBoxSpy).not.toHaveBeenCalled();
|
||||
expect(showAndLogErrorMessageSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showAndLogErrorMessageSpy).toHaveBeenCalledWith(
|
||||
expect.stringMatching(/Expected 'dataExtensions' to be/),
|
||||
expect.stringMatching(/my-extension-pack/),
|
||||
expect.anything(),
|
||||
);
|
||||
expect(cliServer.resolveQlpacks).toHaveBeenCalled();
|
||||
expect(cliServer.resolveExtensions).toHaveBeenCalled();
|
||||
expect(cliServer.resolveExtensions).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("shows an error when the pack YAML dataExtensions is invalid", async () => {
|
||||
@@ -714,10 +698,6 @@ describe("pickExtensionPackModelFile", () => {
|
||||
}),
|
||||
);
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce(undefined);
|
||||
showAndLogErrorMessageSpy.mockResolvedValue(undefined);
|
||||
|
||||
@@ -730,13 +710,26 @@ describe("pickExtensionPackModelFile", () => {
|
||||
),
|
||||
).toEqual(undefined);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledWith(
|
||||
[
|
||||
{
|
||||
label: expect.stringMatching(/create/i),
|
||||
extensionPack: null,
|
||||
},
|
||||
],
|
||||
{
|
||||
title: "Select extension pack to use",
|
||||
},
|
||||
token,
|
||||
);
|
||||
expect(showInputBoxSpy).not.toHaveBeenCalled();
|
||||
expect(showAndLogErrorMessageSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showAndLogErrorMessageSpy).toHaveBeenCalledWith(
|
||||
expect.stringMatching(/Expected 'dataExtensions' to be/),
|
||||
expect.stringMatching(/my-extension-pack/),
|
||||
expect.anything(),
|
||||
);
|
||||
expect(cliServer.resolveQlpacks).toHaveBeenCalled();
|
||||
expect(cliServer.resolveExtensions).toHaveBeenCalled();
|
||||
expect(cliServer.resolveExtensions).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows cancelling the new file input box", async () => {
|
||||
@@ -744,29 +737,24 @@ describe("pickExtensionPackModelFile", () => {
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
const newExtensionPack = await createMockExtensionPack(
|
||||
tmpDir.path,
|
||||
"new-extension-pack",
|
||||
);
|
||||
|
||||
const cliServer = mockCliServer(
|
||||
{
|
||||
"my-extension-pack": [tmpDir.path],
|
||||
},
|
||||
{ models: [], data: {} },
|
||||
);
|
||||
|
||||
await outputFile(
|
||||
join(tmpDir.path, "codeql-pack.yml"),
|
||||
dumpYaml({
|
||||
name: "my-extension-pack",
|
||||
version: "0.0.0",
|
||||
library: true,
|
||||
extensionTargets: {
|
||||
"codeql/java-all": "*",
|
||||
},
|
||||
dataExtensions: ["models/**/*.yml"],
|
||||
}),
|
||||
{
|
||||
models: [],
|
||||
data: {},
|
||||
},
|
||||
);
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
label: "new-extension-pack",
|
||||
extensionPack: newExtensionPack,
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce(undefined);
|
||||
showInputBoxSpy.mockResolvedValue(undefined);
|
||||
@@ -833,36 +821,31 @@ describe("pickExtensionPackModelFile", () => {
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
const extensionPack = await createMockExtensionPack(
|
||||
tmpDir.path,
|
||||
"new-extension-pack",
|
||||
{
|
||||
dataExtensions: ["models/**/*.yml", "data/**/*.yml"],
|
||||
},
|
||||
);
|
||||
|
||||
const cliServer = mockCliServer(
|
||||
{
|
||||
"my-extension-pack": [tmpDir.path],
|
||||
"new-extension-pack": [extensionPack.path],
|
||||
},
|
||||
{ models: [], data: {} },
|
||||
);
|
||||
|
||||
const qlpackPath = join(tmpDir.path, "codeql-pack.yml");
|
||||
await outputFile(
|
||||
qlpackPath,
|
||||
dumpYaml({
|
||||
name: "my-extension-pack",
|
||||
version: "0.0.0",
|
||||
library: true,
|
||||
extensionTargets: {
|
||||
"codeql/java-all": "*",
|
||||
},
|
||||
dataExtensions: ["models/**/*.yml", "data/**/*.yml"],
|
||||
}),
|
||||
);
|
||||
await outputFile(
|
||||
join(tmpDir.path, "models", "model.yml"),
|
||||
join(extensionPack.path, "models", "model.yml"),
|
||||
dumpYaml({
|
||||
extensions: [],
|
||||
}),
|
||||
);
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
label: "new-extension-pack",
|
||||
extensionPack,
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce(undefined);
|
||||
showInputBoxSpy.mockResolvedValue(undefined);
|
||||
@@ -893,10 +876,10 @@ describe("pickExtensionPackModelFile", () => {
|
||||
"File must be in the extension pack",
|
||||
);
|
||||
expect(await validateFile("model.yml")).toEqual(
|
||||
`File must match one of the patterns in 'dataExtensions' in ${qlpackPath}`,
|
||||
`File must match one of the patterns in 'dataExtensions' in ${extensionPack.yamlPath}`,
|
||||
);
|
||||
expect(await validateFile("models/model.yaml")).toEqual(
|
||||
`File must match one of the patterns in 'dataExtensions' in ${qlpackPath}`,
|
||||
`File must match one of the patterns in 'dataExtensions' in ${extensionPack.yamlPath}`,
|
||||
);
|
||||
expect(await validateFile("models/my-model.yml")).toBeUndefined();
|
||||
expect(await validateFile("models/nested/model.yml")).toBeUndefined();
|
||||
@@ -910,7 +893,7 @@ describe("pickExtensionPackModelFile", () => {
|
||||
|
||||
const cliServer = mockCliServer(
|
||||
{
|
||||
"my-extension-pack": [tmpDir.path],
|
||||
"new-extension-pack": [tmpDir.path],
|
||||
},
|
||||
{ models: [], data: {} },
|
||||
);
|
||||
@@ -919,7 +902,7 @@ describe("pickExtensionPackModelFile", () => {
|
||||
await outputFile(
|
||||
qlpackPath,
|
||||
dumpYaml({
|
||||
name: "my-extension-pack",
|
||||
name: "new-extension-pack",
|
||||
version: "0.0.0",
|
||||
library: true,
|
||||
extensionTargets: {
|
||||
@@ -936,8 +919,17 @@ describe("pickExtensionPackModelFile", () => {
|
||||
);
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce({
|
||||
label: "my-extension-pack",
|
||||
extensionPack: "my-extension-pack",
|
||||
label: "new-extension-pack",
|
||||
extensionPack: {
|
||||
path: tmpDir.path,
|
||||
yamlPath: qlpackPath,
|
||||
name: "new-extension-pack",
|
||||
version: "0.0.0",
|
||||
extensionTargets: {
|
||||
"codeql/java-all": "*",
|
||||
},
|
||||
dataExtensions: ["models/**/*.yml"],
|
||||
},
|
||||
} as QuickPickItem);
|
||||
showQuickPickSpy.mockResolvedValueOnce(undefined);
|
||||
showInputBoxSpy.mockResolvedValue(undefined);
|
||||
@@ -959,6 +951,63 @@ describe("pickExtensionPackModelFile", () => {
|
||||
|
||||
expect(await validateFile("models/my-model.yml")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("only shows extension packs for the database language", async () => {
|
||||
const csharpPack = await createMockExtensionPack(
|
||||
join(tmpDir, "csharp-extensions"),
|
||||
"csharp-extension-pack",
|
||||
{
|
||||
version: "0.5.3",
|
||||
extensionTargets: {
|
||||
"codeql/csharp-all": "*",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const cliServer = mockCliServer(
|
||||
{
|
||||
...qlPacks,
|
||||
"csharp-extension-pack": [csharpPack.path],
|
||||
},
|
||||
extensions,
|
||||
);
|
||||
|
||||
showQuickPickSpy.mockResolvedValueOnce(undefined);
|
||||
|
||||
expect(
|
||||
await pickExtensionPackModelFile(
|
||||
cliServer,
|
||||
{
|
||||
...databaseItem,
|
||||
language: "csharp",
|
||||
},
|
||||
progress,
|
||||
token,
|
||||
),
|
||||
).toEqual(undefined);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledTimes(1);
|
||||
expect(showQuickPickSpy).toHaveBeenCalledWith(
|
||||
[
|
||||
{
|
||||
label: "csharp-extension-pack",
|
||||
description: "0.5.3",
|
||||
detail: csharpPack.path,
|
||||
extensionPack: csharpPack,
|
||||
},
|
||||
{
|
||||
label: expect.stringMatching(/create/i),
|
||||
extensionPack: null,
|
||||
},
|
||||
],
|
||||
{
|
||||
title: expect.any(String),
|
||||
},
|
||||
token,
|
||||
);
|
||||
expect(cliServer.resolveQlpacks).toHaveBeenCalledTimes(1);
|
||||
expect(cliServer.resolveQlpacks).toHaveBeenCalledWith([], true);
|
||||
expect(cliServer.resolveExtensions).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
function mockCliServer(
|
||||
@@ -970,3 +1019,40 @@ function mockCliServer(
|
||||
resolveExtensions: jest.fn().mockResolvedValue(extensions),
|
||||
};
|
||||
}
|
||||
|
||||
async function createMockExtensionPack(
|
||||
path: string,
|
||||
name: string,
|
||||
data: Partial<ExtensionPack> = {},
|
||||
): Promise<ExtensionPack> {
|
||||
const extensionPack: ExtensionPack = {
|
||||
path,
|
||||
yamlPath: join(path, "codeql-pack.yml"),
|
||||
name,
|
||||
version: "0.0.0",
|
||||
extensionTargets: {
|
||||
"codeql/java-all": "*",
|
||||
},
|
||||
dataExtensions: ["models/**/*.yml"],
|
||||
...data,
|
||||
};
|
||||
|
||||
await writeExtensionPackToDisk(extensionPack);
|
||||
|
||||
return extensionPack;
|
||||
}
|
||||
|
||||
async function writeExtensionPackToDisk(
|
||||
extensionPack: ExtensionPack,
|
||||
): Promise<void> {
|
||||
await outputFile(
|
||||
extensionPack.yamlPath,
|
||||
dumpYaml({
|
||||
name: extensionPack.name,
|
||||
version: extensionPack.version,
|
||||
library: true,
|
||||
extensionTargets: extensionPack.extensionTargets,
|
||||
dataExtensions: extensionPack.dataExtensions,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user