Do not show non-workspace packs when installing pack dependencies

When using the "CodeQL: Install pack dependencies" command, we would
show packs that are located in the package cache or distribution. Since
there are no dependencies to install for these packs, these options are
not useful.

This will filter out any packs that are not in the workspace folders
when showing the quick pick. This should exclude most packs if you are
in a workspace without the `codeql` submodule and should be a lot more
intuitive in those cases. If you are in a workspace with the `codeql`
submodule, it will still show all the packs.
This commit is contained in:
Koen Vlaswinkel
2023-10-12 11:39:29 +02:00
parent 1993db5122
commit a2a7002263
2 changed files with 76 additions and 5 deletions

View File

@@ -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<QLPackQuickPickItem>(([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),
),
),
),
);
}

View File

@@ -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(