Skip to content

Commit 9d6c78b

Browse files
authored
Merge branch 'main' into koesie10/ast-cfg-typed-commands
2 parents 17bab1c + 56c83eb commit 9d6c78b

File tree

11 files changed

+277
-104
lines changed

11 files changed

+277
-104
lines changed

extensions/ql-vscode/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## [UNRELEASED]
44

55
- Show data flow paths of a variant analysis in a new tab
6+
- Show labels of entities in exported CSV results [#2170](https://github.com/github/vscode-codeql/pull/2170)
67

78
## 1.8.0 - 9 March 2023
89

extensions/ql-vscode/src/common/commands.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,27 +78,42 @@ export type QueryHistoryCommands = {
7878

7979
// Commands used for the local databases panel
8080
export type LocalDatabasesCommands = {
81-
"codeQL.setCurrentDatabase": (uri: Uri) => Promise<void>;
82-
"codeQL.setDefaultTourDatabase": () => Promise<void>;
81+
// Command palette commands
82+
"codeQL.chooseDatabaseFolder": () => Promise<void>;
83+
"codeQL.chooseDatabaseArchive": () => Promise<void>;
84+
"codeQL.chooseDatabaseInternet": () => Promise<void>;
85+
"codeQL.chooseDatabaseGithub": () => Promise<void>;
8386
"codeQL.upgradeCurrentDatabase": () => Promise<void>;
8487
"codeQL.clearCache": () => Promise<void>;
8588

89+
// Explorer context menu
90+
"codeQL.setCurrentDatabase": (uri: Uri) => Promise<void>;
91+
92+
// Database panel view title commands
8693
"codeQLDatabases.chooseDatabaseFolder": () => Promise<void>;
8794
"codeQLDatabases.chooseDatabaseArchive": () => Promise<void>;
8895
"codeQLDatabases.chooseDatabaseInternet": () => Promise<void>;
8996
"codeQLDatabases.chooseDatabaseGithub": () => Promise<void>;
97+
"codeQLDatabases.sortByName": () => Promise<void>;
98+
"codeQLDatabases.sortByDateAdded": () => Promise<void>;
99+
100+
// Database panel context menu
90101
"codeQLDatabases.setCurrentDatabase": (
91102
databaseItem: DatabaseItem,
92103
) => Promise<void>;
93-
"codeQLDatabases.sortByName": () => Promise<void>;
94-
"codeQLDatabases.sortByDateAdded": () => Promise<void>;
95-
"codeQLDatabases.removeOrphanedDatabases": () => Promise<void>;
96104

105+
// Database panel selection commands
97106
"codeQLDatabases.removeDatabase": SelectionCommandFunction<DatabaseItem>;
98107
"codeQLDatabases.upgradeDatabase": SelectionCommandFunction<DatabaseItem>;
99108
"codeQLDatabases.renameDatabase": SelectionCommandFunction<DatabaseItem>;
100109
"codeQLDatabases.openDatabaseFolder": SelectionCommandFunction<DatabaseItem>;
101110
"codeQLDatabases.addDatabaseSource": SelectionCommandFunction<DatabaseItem>;
111+
112+
// Codespace template commands
113+
"codeQL.setDefaultTourDatabase": () => Promise<void>;
114+
115+
// Internal commands
116+
"codeQLDatabases.removeOrphanedDatabases": () => Promise<void>;
102117
};
103118

104119
// Commands tied to variant analysis

extensions/ql-vscode/src/extension.ts

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import {
6464
showInformationMessageWithAction,
6565
tmpDir,
6666
tmpDirDisposal,
67+
prepareCodeTour,
6768
} from "./helpers";
6869
import {
6970
asError,
@@ -523,6 +524,14 @@ async function installOrUpdateThenTryActivate(
523524
): Promise<CodeQLExtensionInterface | Record<string, never>> {
524525
await installOrUpdateDistribution(ctx, distributionManager, config);
525526

527+
try {
528+
await prepareCodeTour();
529+
} catch (e: unknown) {
530+
void extLogger.log(
531+
`Could not open tutorial workspace automatically: ${getErrorMessage(e)}`,
532+
);
533+
}
534+
526535
// Display the warnings even if the extension has already activated.
527536
const distributionResult =
528537
await getDistributionDisplayingDistributionWarnings(distributionManager);
@@ -972,49 +981,6 @@ async function activateWithInstalledDistribution(
972981
),
973982
);
974983

975-
ctx.subscriptions.push(
976-
commandRunnerWithProgress(
977-
"codeQL.chooseDatabaseFolder",
978-
(progress: ProgressCallback, token: CancellationToken) =>
979-
databaseUI.chooseDatabaseFolder(progress, token),
980-
{
981-
title: "Choose a Database from a Folder",
982-
},
983-
),
984-
);
985-
ctx.subscriptions.push(
986-
commandRunnerWithProgress(
987-
"codeQL.chooseDatabaseArchive",
988-
(progress: ProgressCallback, token: CancellationToken) =>
989-
databaseUI.chooseDatabaseArchive(progress, token),
990-
{
991-
title: "Choose a Database from an Archive",
992-
},
993-
),
994-
);
995-
ctx.subscriptions.push(
996-
commandRunnerWithProgress(
997-
"codeQL.chooseDatabaseGithub",
998-
async (progress: ProgressCallback, token: CancellationToken) => {
999-
await databaseUI.chooseDatabaseGithub(progress, token);
1000-
},
1001-
{
1002-
title: "Adding database from GitHub",
1003-
},
1004-
),
1005-
);
1006-
ctx.subscriptions.push(
1007-
commandRunnerWithProgress(
1008-
"codeQL.chooseDatabaseInternet",
1009-
(progress: ProgressCallback, token: CancellationToken) =>
1010-
databaseUI.chooseDatabaseInternet(progress, token),
1011-
1012-
{
1013-
title: "Adding database from URL",
1014-
},
1015-
),
1016-
);
1017-
1018984
ctx.subscriptions.push(
1019985
commandRunner("codeQL.copyVersion", async () => {
1020986
const text = `CodeQL extension version: ${

extensions/ql-vscode/src/helpers.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
window as Window,
1717
workspace,
1818
env,
19+
commands,
1920
} from "vscode";
2021
import { CodeQLCliServer, QlpacksInfo } from "./cli";
2122
import { UserCancellationException } from "./commandRunner";
@@ -25,6 +26,7 @@ import { telemetryListener } from "./telemetry";
2526
import { RedactableError } from "./pure/errors";
2627
import { getQlPackPath } from "./pure/ql";
2728
import { dbSchemeToLanguage } from "./common/query-language";
29+
import { isCodespacesTemplate } from "./config";
2830

2931
// Shared temporary folder for the extension.
3032
export const tmpDir = dirSync({
@@ -266,6 +268,51 @@ export function isFolderAlreadyInWorkspace(folderName: string) {
266268
);
267269
}
268270

271+
/** Check if the current workspace is the CodeTour and open the workspace folder.
272+
* Without this, we can't run the code tour correctly.
273+
**/
274+
export async function prepareCodeTour(): Promise<void> {
275+
if (workspace.workspaceFolders?.length) {
276+
const currentFolder = workspace.workspaceFolders[0].uri.fsPath;
277+
278+
const tutorialWorkspacePath = join(
279+
currentFolder,
280+
"tutorial.code-workspace",
281+
);
282+
const toursFolderPath = join(currentFolder, ".tours");
283+
284+
/** We're opening the tutorial workspace, if we detect it.
285+
* This will only happen if the following three conditions are met:
286+
* - the .tours folder exists
287+
* - the tutorial.code-workspace file exists
288+
* - the CODESPACES_TEMPLATE setting doesn't exist (it's only set if the user has already opened
289+
* the tutorial workspace so it's a good indicator that the user is in the folder but has ignored
290+
* the prompt to open the workspace)
291+
*/
292+
if (
293+
(await pathExists(tutorialWorkspacePath)) &&
294+
(await pathExists(toursFolderPath)) &&
295+
!isCodespacesTemplate()
296+
) {
297+
const answer = await showBinaryChoiceDialog(
298+
"We've detected you're in the CodeQL Tour repo. We will need to open the workspace file to continue. Reload?",
299+
);
300+
301+
if (!answer) {
302+
return;
303+
}
304+
305+
const tutorialWorkspaceUri = Uri.parse(tutorialWorkspacePath);
306+
307+
void extLogger.log(
308+
`In prepareCodeTour() method, going to open the tutorial workspace file: ${tutorialWorkspacePath}`,
309+
);
310+
311+
await commands.executeCommand("vscode.openFolder", tutorialWorkspaceUri);
312+
}
313+
}
314+
}
315+
269316
/**
270317
* Provides a utility method to invoke a function only if a minimum time interval has elapsed since
271318
* the last invocation of that function.

extensions/ql-vscode/src/local-databases-ui.ts

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,13 @@ export class DatabaseUI extends DisposableObject {
208208

209209
public getCommands(): LocalDatabasesCommands {
210210
return {
211+
"codeQL.chooseDatabaseFolder":
212+
this.handleChooseDatabaseFolderFromPalette.bind(this),
213+
"codeQL.chooseDatabaseArchive":
214+
this.handleChooseDatabaseArchiveFromPalette.bind(this),
215+
"codeQL.chooseDatabaseInternet":
216+
this.handleChooseDatabaseInternet.bind(this),
217+
"codeQL.chooseDatabaseGithub": this.handleChooseDatabaseGithub.bind(this),
211218
"codeQL.setCurrentDatabase": this.handleSetCurrentDatabase.bind(this),
212219
"codeQL.setDefaultTourDatabase":
213220
this.handleSetDefaultTourDatabase.bind(this),
@@ -242,7 +249,7 @@ export class DatabaseUI extends DisposableObject {
242249
await this.databaseManager.setCurrentDatabaseItem(databaseItem);
243250
}
244251

245-
public async chooseDatabaseFolder(
252+
private async chooseDatabaseFolder(
246253
progress: ProgressCallback,
247254
token: CancellationToken,
248255
): Promise<void> {
@@ -268,6 +275,17 @@ export class DatabaseUI extends DisposableObject {
268275
);
269276
}
270277

278+
private async handleChooseDatabaseFolderFromPalette(): Promise<void> {
279+
return withProgress(
280+
async (progress, token) => {
281+
await this.chooseDatabaseFolder(progress, token);
282+
},
283+
{
284+
title: "Choose a Database from a Folder",
285+
},
286+
);
287+
}
288+
271289
private async handleSetDefaultTourDatabase(): Promise<void> {
272290
return withProgress(
273291
async (progress, token) => {
@@ -392,7 +410,7 @@ export class DatabaseUI extends DisposableObject {
392410
}
393411
}
394412

395-
public async chooseDatabaseArchive(
413+
private async chooseDatabaseArchive(
396414
progress: ProgressCallback,
397415
token: CancellationToken,
398416
): Promise<void> {
@@ -418,50 +436,47 @@ export class DatabaseUI extends DisposableObject {
418436
);
419437
}
420438

421-
public async chooseDatabaseInternet(
422-
progress: ProgressCallback,
423-
token: CancellationToken,
424-
): Promise<DatabaseItem | undefined> {
425-
return await promptImportInternetDatabase(
426-
this.databaseManager,
427-
this.storagePath,
428-
progress,
429-
token,
430-
this.queryServer?.cliServer,
439+
private async handleChooseDatabaseArchiveFromPalette(): Promise<void> {
440+
return withProgress(
441+
async (progress, token) => {
442+
await this.chooseDatabaseArchive(progress, token);
443+
},
444+
{
445+
title: "Choose a Database from an Archive",
446+
},
431447
);
432448
}
433449

434450
private async handleChooseDatabaseInternet(): Promise<void> {
435451
return withProgress(
436452
async (progress, token) => {
437-
await this.chooseDatabaseInternet(progress, token);
453+
await promptImportInternetDatabase(
454+
this.databaseManager,
455+
this.storagePath,
456+
progress,
457+
token,
458+
this.queryServer?.cliServer,
459+
);
438460
},
439461
{
440462
title: "Adding database from URL",
441463
},
442464
);
443465
}
444466

445-
public async chooseDatabaseGithub(
446-
progress: ProgressCallback,
447-
token: CancellationToken,
448-
): Promise<DatabaseItem | undefined> {
449-
const credentials = isCanary() ? this.app.credentials : undefined;
450-
451-
return await promptImportGithubDatabase(
452-
this.databaseManager,
453-
this.storagePath,
454-
credentials,
455-
progress,
456-
token,
457-
this.queryServer?.cliServer,
458-
);
459-
}
460-
461467
private async handleChooseDatabaseGithub(): Promise<void> {
462468
return withProgress(
463469
async (progress, token) => {
464-
await this.chooseDatabaseGithub(progress, token);
470+
const credentials = isCanary() ? this.app.credentials : undefined;
471+
472+
await promptImportGithubDatabase(
473+
this.databaseManager,
474+
this.storagePath,
475+
credentials,
476+
progress,
477+
token,
478+
this.queryServer?.cliServer,
479+
);
465480
},
466481
{
467482
title: "Adding database from GitHub",

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import {
4848
import {
4949
deserializeQueryHistory,
5050
serializeQueryHistory,
51-
} from "../query-serialization";
51+
} from "./store/query-history-store";
5252
import { pathExists } from "fs-extra";
5353
import { CliVersionConstraint } from "../cli";
5454
import { HistoryItemLabelProvider } from "./history-item-label-provider";

extensions/ql-vscode/src/query-serialization.ts renamed to extensions/ql-vscode/src/query-history/store/query-history-store.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import { pathExists, readFile, remove, mkdir, writeFile } from "fs-extra";
22
import { dirname } from "path";
33

4-
import { showAndLogExceptionWithTelemetry } from "./helpers";
4+
import { showAndLogExceptionWithTelemetry } from "../../helpers";
55
import {
66
asError,
77
asyncFilter,
88
getErrorMessage,
99
getErrorStack,
10-
} from "./pure/helpers-pure";
11-
import { CompletedQueryInfo, LocalQueryInfo } from "./query-results";
12-
import { QueryHistoryInfo } from "./query-history/query-history-info";
13-
import { QueryEvaluationInfo } from "./run-queries-shared";
14-
import { QueryResultType } from "./pure/legacy-messages";
15-
import { redactableError } from "./pure/errors";
10+
} from "../../pure/helpers-pure";
11+
import { CompletedQueryInfo, LocalQueryInfo } from "../../query-results";
12+
import { QueryHistoryInfo } from "../query-history-info";
13+
import { QueryEvaluationInfo } from "../../run-queries-shared";
14+
import { QueryResultType } from "../../pure/legacy-messages";
15+
import { redactableError } from "../../pure/errors";
1616

1717
export async function deserializeQueryHistory(
1818
fsPath: string,

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { nanoid } from "nanoid";
3030
import { CodeQLCliServer } from "./cli";
3131
import { SELECT_QUERY_NAME } from "./contextual/locationFinder";
3232
import { DatabaseManager } from "./local-databases";
33-
import { DecodedBqrsChunk } from "./pure/bqrs-cli-types";
33+
import { DecodedBqrsChunk, EntityValue } from "./pure/bqrs-cli-types";
3434
import { extLogger, Logger } from "./common";
3535
import { generateSummarySymbolsFile } from "./log-insights/summary-parser";
3636
import { getErrorMessage } from "./pure/helpers-pure";
@@ -351,11 +351,17 @@ export class QueryEvaluationInfo {
351351
chunk.tuples.forEach((tuple) => {
352352
out.write(
353353
`${tuple
354-
.map((v, i) =>
355-
chunk.columns[i].kind === "String"
356-
? `"${typeof v === "string" ? v.replaceAll('"', '""') : v}"`
357-
: v,
358-
)
354+
.map((v, i) => {
355+
if (chunk.columns[i].kind === "String") {
356+
return `"${
357+
typeof v === "string" ? v.replaceAll('"', '""') : v
358+
}"`;
359+
} else if (chunk.columns[i].kind === "Entity") {
360+
return (v as EntityValue).label;
361+
} else {
362+
return v;
363+
}
364+
})
359365
.join(",")}\n`,
360366
);
361367
});

extensions/ql-vscode/supported_cli_versions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[
2-
"v2.12.4",
2+
"v2.12.5",
33
"v2.11.6",
44
"v2.7.6",
55
"v2.8.5",

0 commit comments

Comments
 (0)