diff --git a/extensions/ql-vscode/src/packaging/packaging.ts b/extensions/ql-vscode/src/packaging/packaging.ts index 30becc575be..b32c7fcc1bc 100644 --- a/extensions/ql-vscode/src/packaging/packaging.ts +++ b/extensions/ql-vscode/src/packaging/packaging.ts @@ -1,4 +1,4 @@ -import { CodeQLCliServer } from "../codeql-cli/cli"; +import { CodeQLCliServer, QlpacksInfo } from "../codeql-cli/cli"; import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders"; import { QuickPickItem, window } from "vscode"; import { @@ -16,6 +16,7 @@ import { redactableError } from "../common/errors"; import { PACKS_BY_QUERY_LANGUAGE } from "../common/query-language"; import { PackagingCommands } from "../common/commands"; import { telemetryListener } from "../common/vscode/telemetry"; +import { containsPath } from "../common/files"; type PackagingOptions = { cliServer: CodeQLCliServer; @@ -126,9 +127,10 @@ export async function handleInstallPackDependencies( step: 1, maxStep: 2, }); - const workspacePacks = await cliServer.resolveQlpacks( - getOnDiskWorkspaceFolders(), - ); + const workspaceFolders = getOnDiskWorkspaceFolders(); + const resolvedPacks = await cliServer.resolveQlpacks(workspaceFolders); + const workspacePacks = filterWorkspacePacks(resolvedPacks, workspaceFolders); + const quickPickItems = Object.entries( workspacePacks, ).map(([key, value]) => ({ @@ -179,3 +181,27 @@ export async function handleInstallPackDependencies( throw new UserCancellationException("No packs selected."); } } + +/** + * This filter will remove any packs from the qlpacks that are not in the workspace. It will + * filter out any packs that are in e.g. the package cache or in the distribution, which the + * user does not need to install dependencies for. + * + * @param qlpacks The qlpacks to filter. + * @param workspaceFolders The workspace folders to filter by. + */ +export function filterWorkspacePacks( + qlpacks: QlpacksInfo, + workspaceFolders: string[], +): QlpacksInfo { + return Object.fromEntries( + Object.entries(qlpacks).filter(([, packDirs]) => + // If any of the pack dirs are in the workspace, keep the pack + packDirs.some((packDir) => + workspaceFolders.some((workspaceFolder) => + containsPath(workspaceFolder, packDir), + ), + ), + ), + ); +} diff --git a/extensions/ql-vscode/test/vscode-tests/cli-integration/packaging/packaging.test.ts b/extensions/ql-vscode/test/vscode-tests/cli-integration/packaging/packaging.test.ts index 8ddb0732b1c..993f3dc4630 100644 --- a/extensions/ql-vscode/test/vscode-tests/cli-integration/packaging/packaging.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/cli-integration/packaging/packaging.test.ts @@ -12,9 +12,12 @@ import { import { mockedQuickPickItem } from "../../utils/mocking.helpers"; import { getActivatedExtension } from "../../global.helper"; import { - showAndLogInformationMessage, showAndLogExceptionWithTelemetry, + showAndLogInformationMessage, } from "../../../../src/common/logging"; +import * as workspaceFolders from "../../../../src/common/vscode/workspace-folders"; +import { getOnDiskWorkspaceFolders } from "../../../../src/common/vscode/workspace-folders"; +import { pathsEqual } from "../../../../src/common/files"; describe("Packaging commands", () => { let cli: CodeQLCliServer; @@ -87,6 +90,48 @@ describe("Packaging commands", () => { ).toEqual("Unable to download all packs. See log for more details."); }); + it("should only show workspace packs", async () => { + const originalWorkspaceFolders = getOnDiskWorkspaceFolders(); + + // Remove the CodeQL workspace folder from the list of workspace folders + // since that includes all the packs that are already in the package cache, + // so the test would be useless if we included it since nothing would be + // filtered out (except for maybe the distribution legacy-upgrades). + jest + .spyOn(workspaceFolders, "getOnDiskWorkspaceFolders") + .mockReturnValue( + originalWorkspaceFolders.filter( + (folder) => !pathsEqual(folder, process.env.TEST_CODEQL_PATH ?? ""), + ), + ); + + const rootDir = join(__dirname, "../data"); + quickPickSpy.mockResolvedValue( + mockedQuickPickItem([ + { + label: "integration-test-queries-javascript", + packRootDir: [rootDir], + }, + ]), + ); + + await handleInstallPackDependencies(cli, progress); + expect(quickPickSpy).toHaveBeenCalledWith( + [ + expect.objectContaining({ + label: "integration-test-debugger-javascript", + }), + expect.objectContaining({ + label: "semmle/has-extension", + }), + expect.objectContaining({ + label: "semmle/targets-extension", + }), + ], + expect.anything(), + ); + }); + it("should install valid workspace pack", async () => { const rootDir = join(__dirname, "../data"); quickPickSpy.mockResolvedValue(