From 923e13fce36e2d9761ac3465f78d7a5ab41cc63d Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Mon, 17 Apr 2023 14:25:57 +0200 Subject: [PATCH] Add better support for different languages in data extension editor There were still some places where we were hardcoding Java in the data extension editor. This changes these places to use the database item language instead. --- .../data-extensions-editor-view.ts | 6 +- .../extension-pack-picker.ts | 8 +-- .../src/data-extensions-editor/yaml.ts | 3 +- .../data-extensions-editor/yaml.test.ts | 27 ++++++++ .../extension-pack-picker.test.ts | 66 +++++++++++++++++++ 5 files changed, 104 insertions(+), 6 deletions(-) diff --git a/extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts b/extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts index f1835c9efda..24d08e76975 100644 --- a/extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts +++ b/extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts @@ -148,7 +148,11 @@ export class DataExtensionsEditorView extends AbstractWebview< externalApiUsages: ExternalApiUsage[], modeledMethods: Record, ): Promise { - const yaml = createDataExtensionYaml(externalApiUsages, modeledMethods); + const yaml = createDataExtensionYaml( + this.databaseItem.language, + externalApiUsages, + modeledMethods, + ); await outputFile(this.modelFilename, yaml); diff --git a/extensions/ql-vscode/src/data-extensions-editor/extension-pack-picker.ts b/extensions/ql-vscode/src/data-extensions-editor/extension-pack-picker.ts index df47932a45a..87f2d722030 100644 --- a/extensions/ql-vscode/src/data-extensions-editor/extension-pack-picker.ts +++ b/extensions/ql-vscode/src/data-extensions-editor/extension-pack-picker.ts @@ -23,7 +23,7 @@ const packNameLength = 128; export async function pickExtensionPackModelFile( cliServer: Pick, - databaseItem: Pick, + databaseItem: Pick, progress: ProgressCallback, token: CancellationToken, ): Promise { @@ -53,7 +53,7 @@ export async function pickExtensionPackModelFile( async function pickExtensionPack( cliServer: Pick, - databaseItem: Pick, + databaseItem: Pick, progress: ProgressCallback, token: CancellationToken, ): Promise { @@ -184,7 +184,7 @@ async function pickModelFile( } async function pickNewExtensionPack( - databaseItem: Pick, + databaseItem: Pick, token: CancellationToken, ): Promise { const workspaceFolders = getOnDiskWorkspaceFoldersObjects(); @@ -257,7 +257,7 @@ async function pickNewExtensionPack( version: "0.0.0", library: true, extensionTargets: { - "codeql/java-all": "*", + [`codeql/${databaseItem.language}-all`]: "*", }, dataExtensions: ["models/**/*.yml"], }), diff --git a/extensions/ql-vscode/src/data-extensions-editor/yaml.ts b/extensions/ql-vscode/src/data-extensions-editor/yaml.ts index 9cd869543c6..9032727487f 100644 --- a/extensions/ql-vscode/src/data-extensions-editor/yaml.ts +++ b/extensions/ql-vscode/src/data-extensions-editor/yaml.ts @@ -43,6 +43,7 @@ function createDataProperty( } export function createDataExtensionYaml( + language: string, externalApiUsages: ExternalApiUsage[], modeledMethods: Record, ) { @@ -69,7 +70,7 @@ export function createDataExtensionYaml( const extensions = Object.entries(extensiblePredicateDefinitions).map( ([type, definition]) => ` - addsTo: - pack: codeql/java-all + pack: codeql/${language}-all extensible: ${definition.extensiblePredicate} data:${createDataProperty( methodsByType[type as Exclude], diff --git a/extensions/ql-vscode/test/unit-tests/data-extensions-editor/yaml.test.ts b/extensions/ql-vscode/test/unit-tests/data-extensions-editor/yaml.test.ts index dde07e6a43f..a499e12ebd5 100644 --- a/extensions/ql-vscode/test/unit-tests/data-extensions-editor/yaml.test.ts +++ b/extensions/ql-vscode/test/unit-tests/data-extensions-editor/yaml.test.ts @@ -6,6 +6,7 @@ import { describe("createDataExtensionYaml", () => { it("creates the correct YAML file", () => { const yaml = createDataExtensionYaml( + "java", [ { signature: "org.sql2o.Connection#createQuery(String)", @@ -99,6 +100,32 @@ describe("createDataExtensionYaml", () => { pack: codeql/java-all extensible: neutralModel data: [] +`); + }); + + it("includes the correct language", () => { + const yaml = createDataExtensionYaml("csharp", [], {}); + + expect(yaml).toEqual(`extensions: + - addsTo: + pack: codeql/csharp-all + extensible: sourceModel + data: [] + + - addsTo: + pack: codeql/csharp-all + extensible: sinkModel + data: [] + + - addsTo: + pack: codeql/csharp-all + extensible: summaryModel + data: [] + + - addsTo: + pack: codeql/csharp-all + extensible: neutralModel + data: [] `); }); }); diff --git a/extensions/ql-vscode/test/vscode-tests/no-workspace/data-extensions-editor/extension-pack-picker.test.ts b/extensions/ql-vscode/test/vscode-tests/no-workspace/data-extensions-editor/extension-pack-picker.test.ts index 2846f6c8850..88ae01773d3 100644 --- a/extensions/ql-vscode/test/vscode-tests/no-workspace/data-extensions-editor/extension-pack-picker.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/no-workspace/data-extensions-editor/extension-pack-picker.test.ts @@ -27,6 +27,7 @@ describe("pickExtensionPackModelFile", () => { }; const databaseItem = { name: "github/vscode-codeql", + language: "java", }; const cancellationTokenSource = new CancellationTokenSource(); @@ -304,6 +305,71 @@ describe("pickExtensionPackModelFile", () => { }); }); + it("allows user to create an extension pack when there are no extension packs with a different language", async () => { + const cliServer = mockCliServer({}, { models: [], data: {} }); + + const tmpDir = await dir({ + unsafeCleanup: true, + }); + + showQuickPickSpy.mockResolvedValueOnce({ + label: "codeql-custom-queries-java", + path: tmpDir.path, + } as QuickPickItem); + showInputBoxSpy.mockResolvedValueOnce("my-extension-pack"); + showInputBoxSpy.mockResolvedValue("models/my-model.yml"); + + expect( + await pickExtensionPackModelFile( + cliServer, + { + ...databaseItem, + language: "csharp", + }, + progress, + token, + ), + ).toEqual(join(tmpDir.path, "my-extension-pack", "models", "my-model.yml")); + expect(showQuickPickSpy).toHaveBeenCalledTimes(1); + expect(showInputBoxSpy).toHaveBeenCalledTimes(2); + expect(showInputBoxSpy).toHaveBeenCalledWith( + { + title: expect.stringMatching(/extension pack/i), + prompt: expect.stringMatching(/extension pack/i), + placeHolder: expect.stringMatching(/github\/vscode-codeql-extensions/), + validateInput: expect.any(Function), + }, + token, + ); + expect(showInputBoxSpy).toHaveBeenCalledWith( + { + title: expect.stringMatching(/model file/), + value: "models/github.vscode-codeql.model.yml", + validateInput: expect.any(Function), + }, + token, + ); + expect(cliServer.resolveQlpacks).toHaveBeenCalled(); + expect(cliServer.resolveExtensions).toHaveBeenCalled(); + + expect( + loadYaml( + await readFile( + join(tmpDir.path, "my-extension-pack", "codeql-pack.yml"), + "utf8", + ), + ), + ).toEqual({ + name: "my-extension-pack", + version: "0.0.0", + library: true, + extensionTargets: { + "codeql/csharp-all": "*", + }, + dataExtensions: ["models/**/*.yml"], + }); + }); + it("allows cancelling the workspace folder selection", async () => { const cliServer = mockCliServer({}, { models: [], data: {} });