Implement the command to download a published pack

This commit is contained in:
Robert
2024-01-16 14:32:00 +00:00
parent 5948008c99
commit b4250218d5
2 changed files with 57 additions and 2 deletions

View File

@@ -121,6 +121,16 @@ type GenerateExtensiblePredicateMetadataResult = {
}>;
};
type PackDownloadResult = {
// There are other properties in this object, but they are
// not relevant for its use in the extension, so we omit them.
packs: Array<{
name: string;
version: string;
}>;
packDir: string;
};
/**
* The expected output of `codeql resolve qlref`.
*/
@@ -1383,7 +1393,7 @@ export class CodeQLCliServer implements Disposable {
* Downloads a specified pack.
* @param packs The `<package-scope/name[@version]>` of the packs to download.
*/
async packDownload(packs: string[]) {
async packDownload(packs: string[]): Promise<PackDownloadResult> {
return this.runJsonCodeQlCliCommandWithAuthentication(
["pack", "download"],
packs,

View File

@@ -87,6 +87,7 @@ import type { QueryTreeViewItem } from "../queries-panel/query-tree-view-item";
import { RequestError } from "@octokit/request-error";
import { handleRequestError } from "./custom-errors";
import { createMultiSelectionCommand } from "../common/vscode/selection-commands";
import { askForLanguage } from "../codeql-cli/query-language";
const maxRetryCount = 3;
@@ -214,7 +215,51 @@ export class VariantAnalysisManager
}
private async runVariantAnalysisFromPublishedPack(): Promise<void> {
throw new Error("Command not yet implemented");
const language = await askForLanguage(this.cliServer);
const packName = `codeql/${language}-queries`;
const packDownloadResult = await this.cliServer.packDownload([packName]);
const downloadedPack = packDownloadResult.packs[0];
const packDir = `${packDownloadResult.packDir}/${downloadedPack.name}/${downloadedPack.version}`;
const suitePath = `${packDir}/codeql-suites/${language}-code-scanning.qls`;
const resolvedQueries = await this.cliServer.resolveQueries(suitePath);
const problemQueries =
await this.filterToOnlyProblemQueries(resolvedQueries);
if (problemQueries.length === 0) {
void this.app.logger.showErrorMessage(
`Unable to trigger variant analysis. No problem queries found in published query pack: ${packName}.`,
);
}
return withProgress((progress, token) =>
this.runVariantAnalysis(
problemQueries.map((q) => Uri.file(q)),
progress,
token,
),
);
}
private async filterToOnlyProblemQueries(
queries: string[],
): Promise<string[]> {
const problemQueries: string[] = [];
for (const query of queries) {
const queryMetadata = await this.cliServer.resolveMetadata(query);
if (
queryMetadata.kind === "problem" ||
queryMetadata.kind === "path-problem"
) {
problemQueries.push(query);
} else {
void this.app.logger.log(`Skipping non-problem query ${query}`);
}
}
return problemQueries;
}
private async runVariantAnalysisCommand(uri: Uri): Promise<void> {