Skip to content

Commit b425021

Browse files
Implement the command to download a published pack
1 parent 5948008 commit b425021

2 files changed

Lines changed: 57 additions & 2 deletions

File tree

extensions/ql-vscode/src/codeql-cli/cli.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@ type GenerateExtensiblePredicateMetadataResult = {
121121
}>;
122122
};
123123

124+
type PackDownloadResult = {
125+
// There are other properties in this object, but they are
126+
// not relevant for its use in the extension, so we omit them.
127+
packs: Array<{
128+
name: string;
129+
version: string;
130+
}>;
131+
packDir: string;
132+
};
133+
124134
/**
125135
* The expected output of `codeql resolve qlref`.
126136
*/
@@ -1383,7 +1393,7 @@ export class CodeQLCliServer implements Disposable {
13831393
* Downloads a specified pack.
13841394
* @param packs The `<package-scope/name[@version]>` of the packs to download.
13851395
*/
1386-
async packDownload(packs: string[]) {
1396+
async packDownload(packs: string[]): Promise<PackDownloadResult> {
13871397
return this.runJsonCodeQlCliCommandWithAuthentication(
13881398
["pack", "download"],
13891399
packs,

extensions/ql-vscode/src/variant-analysis/variant-analysis-manager.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ import type { QueryTreeViewItem } from "../queries-panel/query-tree-view-item";
8787
import { RequestError } from "@octokit/request-error";
8888
import { handleRequestError } from "./custom-errors";
8989
import { createMultiSelectionCommand } from "../common/vscode/selection-commands";
90+
import { askForLanguage } from "../codeql-cli/query-language";
9091

9192
const maxRetryCount = 3;
9293

@@ -214,7 +215,51 @@ export class VariantAnalysisManager
214215
}
215216

216217
private async runVariantAnalysisFromPublishedPack(): Promise<void> {
217-
throw new Error("Command not yet implemented");
218+
const language = await askForLanguage(this.cliServer);
219+
220+
const packName = `codeql/${language}-queries`;
221+
const packDownloadResult = await this.cliServer.packDownload([packName]);
222+
const downloadedPack = packDownloadResult.packs[0];
223+
224+
const packDir = `${packDownloadResult.packDir}/${downloadedPack.name}/${downloadedPack.version}`;
225+
226+
const suitePath = `${packDir}/codeql-suites/${language}-code-scanning.qls`;
227+
const resolvedQueries = await this.cliServer.resolveQueries(suitePath);
228+
229+
const problemQueries =
230+
await this.filterToOnlyProblemQueries(resolvedQueries);
231+
232+
if (problemQueries.length === 0) {
233+
void this.app.logger.showErrorMessage(
234+
`Unable to trigger variant analysis. No problem queries found in published query pack: ${packName}.`,
235+
);
236+
}
237+
238+
return withProgress((progress, token) =>
239+
this.runVariantAnalysis(
240+
problemQueries.map((q) => Uri.file(q)),
241+
progress,
242+
token,
243+
),
244+
);
245+
}
246+
247+
private async filterToOnlyProblemQueries(
248+
queries: string[],
249+
): Promise<string[]> {
250+
const problemQueries: string[] = [];
251+
for (const query of queries) {
252+
const queryMetadata = await this.cliServer.resolveMetadata(query);
253+
if (
254+
queryMetadata.kind === "problem" ||
255+
queryMetadata.kind === "path-problem"
256+
) {
257+
problemQueries.push(query);
258+
} else {
259+
void this.app.logger.log(`Skipping non-problem query ${query}`);
260+
}
261+
}
262+
return problemQueries;
218263
}
219264

220265
private async runVariantAnalysisCommand(uri: Uri): Promise<void> {

0 commit comments

Comments
 (0)