Skip to content

Commit 9046844

Browse files
committed
Add cancellation from query history view
And tweak the commands visible from the view.
1 parent 5a9b49b commit 9046844

7 files changed

Lines changed: 65 additions & 23 deletions

File tree

extensions/ql-vscode/package.json

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,10 @@
496496
"command": "codeQLQueryHistory.showQueryLog",
497497
"title": "Show Query Log"
498498
},
499+
{
500+
"command": "codeQLQueryHistory.cancel",
501+
"title": "Cancel"
502+
},
499503
{
500504
"command": "codeQLQueryHistory.showQueryText",
501505
"title": "Show Query Text"
@@ -664,7 +668,7 @@
664668
{
665669
"command": "codeQLQueryHistory.removeHistoryItem",
666670
"group": "9_qlCommands",
667-
"when": "view == codeQLQueryHistory"
671+
"when": "view == codeQLQueryHistory && viewItem != inProgressResultsItem"
668672
},
669673
{
670674
"command": "codeQLQueryHistory.setLabel",
@@ -674,12 +678,12 @@
674678
{
675679
"command": "codeQLQueryHistory.compareWith",
676680
"group": "9_qlCommands",
677-
"when": "view == codeQLQueryHistory"
681+
"when": "view == codeQLQueryHistory && (viewItem == rawResultsItem || viewItem == interpretedResultsItem)"
678682
},
679683
{
680684
"command": "codeQLQueryHistory.showQueryLog",
681685
"group": "9_qlCommands",
682-
"when": "view == codeQLQueryHistory"
686+
"when": "view == codeQLQueryHistory && (viewItem == rawResultsItem || viewItem == interpretedResultsItem)"
683687
},
684688
{
685689
"command": "codeQLQueryHistory.showQueryText",
@@ -689,7 +693,7 @@
689693
{
690694
"command": "codeQLQueryHistory.viewCsvResults",
691695
"group": "9_qlCommands",
692-
"when": "view == codeQLQueryHistory && viewItem != interpretedResultsItem"
696+
"when": "view == codeQLQueryHistory && viewItem == rawResultsItem"
693697
},
694698
{
695699
"command": "codeQLQueryHistory.viewCsvAlerts",
@@ -704,12 +708,12 @@
704708
{
705709
"command": "codeQLQueryHistory.viewDil",
706710
"group": "9_qlCommands",
707-
"when": "view == codeQLQueryHistory"
711+
"when": "view == codeQLQueryHistory && (viewItem == rawResultsItem || viewItem == interpretedResultsItem)"
708712
},
709713
{
710-
"command": "codeQL.previewQueryHelp",
714+
"command": "codeQLQueryHistory.cancel",
711715
"group": "9_qlCommands",
712-
"when": "view == codeQLQueryHistory && resourceScheme == .qhelp && isWorkspaceTrusted"
716+
"when": "view == codeQLQueryHistory && viewItem == inProgressResultsItem"
713717
},
714718
{
715719
"command": "codeQLTests.showOutputDifferences",
@@ -862,6 +866,10 @@
862866
"command": "codeQLQueryHistory.showQueryLog",
863867
"when": "false"
864868
},
869+
{
870+
"command": "codeQLQueryHistory.cancel",
871+
"when": "false"
872+
},
865873
{
866874
"command": "codeQLQueryHistory.showQueryText",
867875
"when": "false"

extensions/ql-vscode/src/extension.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
CancellationToken,
3+
CancellationTokenSource,
34
commands,
45
Disposable,
56
ExtensionContext,
@@ -498,8 +499,12 @@ async function activateWithInstalledDistribution(
498499
databaseUri: databaseItem.databaseUri.toString(),
499500
};
500501

502+
// handle cancellation from the history view.
503+
const source = new CancellationTokenSource();
504+
token.onCancellationRequested(() => source.cancel());
505+
501506
const initialInfo = await createInitialQueryInfo(selectedQuery, databaseInfo, quickEval, range);
502-
const item = new FullQueryInfo(initialInfo, queryHistoryConfigurationListener);
507+
const item = new FullQueryInfo(initialInfo, queryHistoryConfigurationListener, source);
503508
qhm.addQuery(item);
504509
try {
505510
const completedQueryInfo = await compileAndRunQueryAgainstDatabase(
@@ -508,7 +513,7 @@ async function activateWithInstalledDistribution(
508513
databaseItem,
509514
initialInfo,
510515
progress,
511-
token,
516+
source.token,
512517
);
513518
item.completeThisQuery(completedQueryInfo);
514519
await showResultsForCompletedQuery(item as FullCompletedQueryInfo, WebviewReveal.NotForced);
@@ -519,6 +524,7 @@ async function activateWithInstalledDistribution(
519524
throw e;
520525
} finally {
521526
qhm.refreshTreeView();
527+
source.dispose();
522528
}
523529
}
524530
}

extensions/ql-vscode/src/query-history.ts

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -119,24 +119,24 @@ export class HistoryTreeDataProvider extends DisposableObject {
119119
arguments: [element],
120120
};
121121

122-
// Mark this query history item according to whether it has a
123-
// SARIF file so that we can make context menu items conditionally
124-
// available.
125-
const hasResults = await element.completedQuery?.query.hasInterpretedResults();
126-
treeItem.contextValue = hasResults
127-
? 'interpretedResultsItem'
128-
: 'rawResultsItem';
129-
122+
// Populate the icon and the context value. We use the context value to
123+
// control which commands are visible in the context menu.
124+
let hasResults;
130125
switch (element.status) {
131126
case QueryStatus.InProgress:
132-
// TODO this is not a good icon.
133127
treeItem.iconPath = new ThemeIcon('sync~spin');
128+
treeItem.contextValue = 'inProgressResultsItem';
134129
break;
135130
case QueryStatus.Completed:
131+
hasResults = await element.completedQuery?.query.hasInterpretedResults();
136132
treeItem.iconPath = this.localSuccessIconPath;
133+
treeItem.contextValue = hasResults
134+
? 'interpretedResultsItem'
135+
: 'rawResultsItem';
137136
break;
138137
case QueryStatus.Failed:
139138
treeItem.iconPath = this.failedIconPath;
139+
treeItem.contextValue = 'cancelledResultsItem';
140140
break;
141141
default:
142142
assertNever(element.status);
@@ -332,6 +332,12 @@ export class QueryHistoryManager extends DisposableObject {
332332
this.handleShowQueryLog.bind(this)
333333
)
334334
);
335+
this.push(
336+
commandRunner(
337+
'codeQLQueryHistory.cancel',
338+
this.handleCancel.bind(this)
339+
)
340+
);
335341
this.push(
336342
commandRunner(
337343
'codeQLQueryHistory.showQueryText',
@@ -439,7 +445,7 @@ export class QueryHistoryManager extends DisposableObject {
439445
const { finalSingleItem, finalMultiSelect } = this.determineSelection(singleItem, multiSelect);
440446

441447
(finalMultiSelect || [finalSingleItem]).forEach((item) => {
442-
// TODO: Removing in progress queries is not supported yet
448+
// Removing in progress queries is not supported yet
443449
if (item.status !== QueryStatus.InProgress) {
444450
this.treeDataProvider.remove(item);
445451
item.completedQuery?.dispose();
@@ -568,6 +574,19 @@ export class QueryHistoryManager extends DisposableObject {
568574
}
569575
}
570576

577+
async handleCancel(
578+
singleItem: FullQueryInfo,
579+
multiSelect: FullQueryInfo[]
580+
) {
581+
const { finalSingleItem, finalMultiSelect } = this.determineSelection(singleItem, multiSelect);
582+
583+
(finalMultiSelect || [finalSingleItem]).forEach((item) => {
584+
if (item.status === QueryStatus.InProgress) {
585+
item.cancel();
586+
}
587+
});
588+
}
589+
571590
async handleShowQueryText(
572591
singleItem: FullQueryInfo,
573592
multiSelect: FullQueryInfo[]

extensions/ql-vscode/src/query-results.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { env } from 'vscode';
1+
import { CancellationTokenSource, env } from 'vscode';
22

33
import { QueryWithResults, tmpDir, QueryEvaluationInfo } from './run-queries';
44
import * as messages from './pure/messages';
@@ -180,10 +180,15 @@ export class FullQueryInfo {
180180
constructor(
181181
public readonly initialInfo: InitialQueryInfo,
182182
private readonly config: QueryHistoryConfig,
183+
private readonly source: CancellationTokenSource
183184
) {
184185
/**/
185186
}
186187

188+
cancel() {
189+
this.source.cancel();
190+
}
191+
187192
get startTime() {
188193
return this.initialInfo.start.toLocaleString(env.language);
189194
}

extensions/ql-vscode/src/run-queries.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,8 @@ let queryId = 0;
695695
export async function createInitialQueryInfo(
696696
selectedQueryUri: Uri | undefined,
697697
databaseInfo: DatabaseInfo,
698-
isQuickEval: boolean, range?: Range
698+
isQuickEval: boolean,
699+
range?: Range
699700
): Promise<InitialQueryInfo> {
700701
// Determine which query to run, based on the selection and the active editor.
701702
const { queryPath, quickEvalPosition, quickEvalText } = await determineSelectedQuery(selectedQueryUri, isQuickEval, range);

extensions/ql-vscode/src/vscode-tests/no-workspace/query-history.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,8 @@ describe('query-history', () => {
515515
start: new Date(),
516516
queryPath: 'hucairz'
517517
} as InitialQueryInfo,
518-
configListener
518+
configListener,
519+
{} as vscode.CancellationTokenSource
519520
);
520521

521522
if (queryWitbResults) {

extensions/ql-vscode/src/vscode-tests/no-workspace/query-results.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { EvaluationResult, QueryResultType } from '../../pure/messages';
1212
import { SortDirection, SortedResultSetInfo } from '../../pure/interface-types';
1313
import { CodeQLCliServer, SourceInfo } from '../../cli';
1414
import { env } from 'process';
15+
import { CancellationTokenSource } from 'vscode';
1516

1617
chai.use(chaiAsPromised);
1718
const expect = chai.expect;
@@ -266,7 +267,8 @@ describe('query-results', () => {
266267
start: new Date(),
267268
queryPath: 'path/to/hucairz'
268269
} as InitialQueryInfo,
269-
mockQueryHistoryConfig()
270+
mockQueryHistoryConfig(),
271+
{} as CancellationTokenSource
270272
);
271273

272274
if (queryWitbResults) {

0 commit comments

Comments
 (0)