Skip to content

Commit a559a0a

Browse files
authored
Merge pull request #3454 from github/koesie10/cancellable-variant-analysis
Make the "Run variant analysis against published pack" command cancellable
2 parents 84a8ffd + 695cf34 commit a559a0a

File tree

8 files changed

+397
-178
lines changed

8 files changed

+397
-178
lines changed

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

Lines changed: 330 additions & 137 deletions
Large diffs are not rendered by default.

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { CodeQLCliServer } from "./cli";
2-
import type { Uri } from "vscode";
2+
import type { CancellationToken, Uri } from "vscode";
33
import { window } from "vscode";
44
import {
55
getLanguageDisplayName,
@@ -50,6 +50,7 @@ export async function findLanguage(
5050
export async function askForLanguage(
5151
cliServer: CodeQLCliServer,
5252
throwOnEmpty = true,
53+
token?: CancellationToken,
5354
): Promise<QueryLanguage | undefined> {
5455
const supportedLanguages = await cliServer.getSupportedLanguages();
5556

@@ -62,10 +63,14 @@ export async function askForLanguage(
6263
}))
6364
.sort((a, b) => a.label.localeCompare(b.label));
6465

65-
const selectedItem = await window.showQuickPick(items, {
66-
placeHolder: "Select target query language",
67-
ignoreFocusOut: true,
68-
});
66+
const selectedItem = await window.showQuickPick(
67+
items,
68+
{
69+
placeHolder: "Select target query language",
70+
ignoreFocusOut: true,
71+
},
72+
token,
73+
);
6974
if (!selectedItem) {
7075
// This only happens if the user cancels the quick pick.
7176
if (throwOnEmpty) {

extensions/ql-vscode/src/model-editor/model-evaluator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export class ModelEvaluator extends DisposableObject {
5858
this.app.logger,
5959
this.cliServer,
6060
this.language,
61+
this.cancellationSource.token,
6162
);
6263

6364
if (!qlPack) {

extensions/ql-vscode/src/variant-analysis/code-scanning-pack.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@ import type { QlPackDetails } from "./ql-pack-details";
99
import { getQlPackFilePath } from "../common/ql";
1010
import type { SuiteInstruction } from "../packaging/suite-instruction";
1111
import { SARIF_RESULTS_QUERY_KINDS } from "../common/query-metadata";
12+
import type { CancellationToken } from "vscode";
1213

1314
export async function resolveCodeScanningQueryPack(
1415
logger: BaseLogger,
1516
cliServer: CodeQLCliServer,
1617
language: QueryLanguage,
18+
token: CancellationToken,
1719
): Promise<QlPackDetails> {
1820
// Get pack
1921
void logger.log(`Downloading pack for language: ${language}`);
2022
const packName = `codeql/${language}-queries`;
21-
const packDownloadResult = await cliServer.packDownload([packName]);
23+
const packDownloadResult = await cliServer.packDownload([packName], token);
2224
const downloadedPack = packDownloadResult.packs[0];
2325

2426
const packDir = join(

extensions/ql-vscode/src/variant-analysis/run-remote-query.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ async function generateQueryPack(
5454
cliServer: CodeQLCliServer,
5555
qlPackDetails: QlPackDetails,
5656
tmpDir: RemoteQueryTempDir,
57+
token: CancellationToken,
5758
): Promise<string> {
5859
const workspaceFolders = getOnDiskWorkspaceFolders();
5960
const extensionPacks = await getExtensionPacksToInject(
@@ -148,6 +149,7 @@ async function generateQueryPack(
148149
bundlePath,
149150
tmpDir.compiledPackDir,
150151
precompilationOpts,
152+
token,
151153
);
152154
const base64Pack = (await readFile(bundlePath)).toString("base64");
153155
return base64Pack;
@@ -331,7 +333,12 @@ export async function prepareRemoteQueryRun(
331333
let base64Pack: string;
332334

333335
try {
334-
base64Pack = await generateQueryPack(cliServer, qlPackDetails, tempDir);
336+
base64Pack = await generateQueryPack(
337+
cliServer,
338+
qlPackDetails,
339+
tempDir,
340+
token,
341+
);
335342
} finally {
336343
await tempDir.remoteQueryDir.cleanup();
337344
}

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

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -221,42 +221,49 @@ export class VariantAnalysisManager
221221
}
222222

223223
public async runVariantAnalysisFromPublishedPack(): Promise<void> {
224-
return withProgress(async (progress, token) => {
225-
progress({
226-
maxStep: 7,
227-
step: 0,
228-
message: "Determining query language",
229-
});
230-
231-
const language = await askForLanguage(this.cliServer);
232-
if (!language) {
233-
return;
234-
}
235-
236-
progress({
237-
maxStep: 7,
238-
step: 2,
239-
message: "Downloading query pack and resolving queries",
240-
});
224+
return withProgress(
225+
async (progress, token) => {
226+
progress({
227+
maxStep: 7,
228+
step: 0,
229+
message: "Determining query language",
230+
});
231+
232+
const language = await askForLanguage(this.cliServer, true, token);
233+
if (!language) {
234+
return;
235+
}
241236

242-
// Build up details to pass to the functions that run the variant analysis.
243-
const qlPackDetails = await resolveCodeScanningQueryPack(
244-
this.app.logger,
245-
this.cliServer,
246-
language,
247-
);
237+
progress({
238+
maxStep: 7,
239+
step: 2,
240+
message: "Downloading query pack and resolving queries",
241+
});
242+
243+
// Build up details to pass to the functions that run the variant analysis.
244+
const qlPackDetails = await resolveCodeScanningQueryPack(
245+
this.app.logger,
246+
this.cliServer,
247+
language,
248+
token,
249+
);
248250

249-
await this.runVariantAnalysis(
250-
qlPackDetails,
251-
(p) =>
252-
progress({
253-
...p,
254-
maxStep: p.maxStep + 3,
255-
step: p.step + 3,
256-
}),
257-
token,
258-
);
259-
});
251+
await this.runVariantAnalysis(
252+
qlPackDetails,
253+
(p) =>
254+
progress({
255+
...p,
256+
maxStep: p.maxStep + 3,
257+
step: p.step + 3,
258+
}),
259+
token,
260+
);
261+
},
262+
{
263+
title: "Run Variant Analysis",
264+
cancellable: true,
265+
},
266+
);
260267
}
261268

262269
private async runVariantAnalysisCommand(queryFiles: Uri[]): Promise<void> {

extensions/ql-vscode/test/vscode-tests/cli-integration/jest.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ const config: Config = {
99
// CLI integration tests call into the CLI and execute queries, so these are expected to take a lot longer
1010
// than the default 5 seconds.
1111
testTimeout: 180_000, // 3 minutes
12+
// Ensure that Jest exits even when there are some remaining handles open
13+
forceExit: true,
1214
};
1315

1416
export default config;

extensions/ql-vscode/test/vscode-tests/cli-integration/variant-analysis/code-scanning-pack.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { CancellationTokenSource } from "vscode";
12
import type { CodeQLCliServer } from "../../../../src/codeql-cli/cli";
23
import type { App } from "../../../../src/common/app";
34
import { QueryLanguage } from "../../../../src/common/query-language";
@@ -20,6 +21,7 @@ describe("Code Scanning pack", () => {
2021
app.logger,
2122
cli,
2223
QueryLanguage.Javascript,
24+
new CancellationTokenSource().token,
2325
);
2426
// Should include queries. Just check that at least one known query exists.
2527
// It doesn't particularly matter which query we check for.

0 commit comments

Comments
 (0)