Skip to content

Commit ac93074

Browse files
author
Dave Bartolomeo
committed
Merge remote-tracking branch 'origin/main' into dbartol/new-test-api
2 parents 1dc6111 + f9166f3 commit ac93074

9 files changed

Lines changed: 580 additions & 68 deletions

File tree

extensions/ql-vscode/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22

33
## [UNRELEASED]
44

5+
- If you run a query without having selected a database, we show a more intuitive prompt to help you select a database. [#3214](https://github.com/github/vscode-codeql/pull/3214)
6+
7+
## 1.12.0 - 11 January 2024
8+
59
- Add a prompt for downloading a GitHub database when opening a GitHub repository. [#3138](https://github.com/github/vscode-codeql/pull/3138)
610
- Avoid showing a popup when hovering over source elements in database source files. [#3125](https://github.com/github/vscode-codeql/pull/3125)
711
- Add comparison of alerts when comparing query results. This allows viewing path explanations for differences in alerts. [#3113](https://github.com/github/vscode-codeql/pull/3113)
812
- Fix a bug where the CodeQL CLI and variant analysis results were corrupted after extraction in VS Code Insiders. [#3151](https://github.com/github/vscode-codeql/pull/3151) & [#3152](https://github.com/github/vscode-codeql/pull/3152)
13+
- Show progress when extracting the CodeQL CLI distribution during installation. [#3157](https://github.com/github/vscode-codeql/pull/3157)
914
- Add option to cancel opening the model editor. [#3189](https://github.com/github/vscode-codeql/pull/3189)
1015

1116
## 1.11.0 - 13 December 2023

extensions/ql-vscode/package-lock.json

Lines changed: 9 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/ql-vscode/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "CodeQL for Visual Studio Code",
55
"author": "GitHub",
66
"private": true,
7-
"version": "1.11.1",
7+
"version": "1.12.1",
88
"publisher": "GitHub",
99
"license": "MIT",
1010
"icon": "media/VS-marketplace-CodeQL-icon.png",
@@ -2005,7 +2005,7 @@
20052005
"eslint-plugin-github": "^4.4.1",
20062006
"eslint-plugin-import": "^2.29.1",
20072007
"eslint-plugin-jest-dom": "^5.0.1",
2008-
"eslint-plugin-prettier": "^5.0.0",
2008+
"eslint-plugin-prettier": "^5.1.3",
20092009
"eslint-plugin-react": "^7.31.8",
20102010
"eslint-plugin-react-hooks": "^4.6.0",
20112011
"eslint-plugin-storybook": "^0.6.4",

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

Lines changed: 132 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
ProviderResult,
66
TreeDataProvider,
77
CancellationToken,
8+
QuickPickItem,
89
} from "vscode";
910
import {
1011
EventEmitter,
@@ -28,7 +29,11 @@ import type {
2829
ProgressCallback,
2930
ProgressContext,
3031
} from "../common/vscode/progress";
31-
import { withInheritedProgress, withProgress } from "../common/vscode/progress";
32+
import {
33+
UserCancellationException,
34+
withInheritedProgress,
35+
withProgress,
36+
} from "../common/vscode/progress";
3237
import {
3338
isLikelyDatabaseRoot,
3439
isLikelyDbLanguageFolder,
@@ -52,7 +57,10 @@ import {
5257
createMultiSelectionCommand,
5358
createSingleSelectionCommand,
5459
} from "../common/vscode/selection-commands";
55-
import { tryGetQueryLanguage } from "../common/query-language";
60+
import {
61+
getLanguageDisplayName,
62+
tryGetQueryLanguage,
63+
} from "../common/query-language";
5664
import type { LanguageContextStore } from "../language-context-store";
5765

5866
enum SortOrder {
@@ -227,6 +235,18 @@ async function chooseDatabaseDir(byFolder: boolean): Promise<Uri | undefined> {
227235
return getFirst(chosen);
228236
}
229237

238+
interface DatabaseSelectionQuickPickItem extends QuickPickItem {
239+
databaseKind: "new" | "existing";
240+
}
241+
242+
export interface DatabaseQuickPickItem extends QuickPickItem {
243+
databaseItem: DatabaseItem;
244+
}
245+
246+
interface DatabaseImportQuickPickItems extends QuickPickItem {
247+
importType: "URL" | "github" | "archive" | "folder";
248+
}
249+
230250
export class DatabaseUI extends DisposableObject {
231251
private treeDataProvider: DatabaseTreeDataProvider;
232252

@@ -794,15 +814,122 @@ export class DatabaseUI extends DisposableObject {
794814
* notification if it tries to perform any long-running operations.
795815
*/
796816
private async getDatabaseItemInternal(
797-
progress: ProgressContext | undefined,
817+
progressContext: ProgressContext | undefined,
798818
): Promise<DatabaseItem | undefined> {
799819
if (this.databaseManager.currentDatabaseItem === undefined) {
800-
await this.chooseAndSetDatabase(false, progress);
820+
progressContext?.progress({
821+
maxStep: 2,
822+
step: 1,
823+
message: "Choosing database",
824+
});
825+
await this.promptForDatabase();
801826
}
802-
803827
return this.databaseManager.currentDatabaseItem;
804828
}
805829

830+
private async promptForDatabase(): Promise<void> {
831+
const quickPickItems: DatabaseSelectionQuickPickItem[] = [
832+
{
833+
label: "$(database) Existing database",
834+
detail: "Select an existing database from your workspace",
835+
alwaysShow: true,
836+
databaseKind: "existing",
837+
},
838+
{
839+
label: "$(arrow-down) New database",
840+
detail: "Import a new database from the cloud or your local machine",
841+
alwaysShow: true,
842+
databaseKind: "new",
843+
},
844+
];
845+
const selectedOption =
846+
await window.showQuickPick<DatabaseSelectionQuickPickItem>(
847+
quickPickItems,
848+
{
849+
placeHolder: "Select an option",
850+
ignoreFocusOut: true,
851+
},
852+
);
853+
854+
if (!selectedOption) {
855+
throw new UserCancellationException("No database selected", true);
856+
}
857+
858+
if (selectedOption.databaseKind === "existing") {
859+
await this.selectExistingDatabase();
860+
} else if (selectedOption.databaseKind === "new") {
861+
await this.importNewDatabase();
862+
}
863+
}
864+
865+
private async selectExistingDatabase() {
866+
const dbItems: DatabaseQuickPickItem[] =
867+
this.databaseManager.databaseItems.map((dbItem) => ({
868+
label: dbItem.name,
869+
description: getLanguageDisplayName(dbItem.language),
870+
databaseItem: dbItem,
871+
}));
872+
873+
const selectedDatabase = await window.showQuickPick(dbItems, {
874+
placeHolder: "Select a database",
875+
ignoreFocusOut: true,
876+
});
877+
878+
if (!selectedDatabase) {
879+
throw new UserCancellationException("No database selected", true);
880+
}
881+
882+
await this.databaseManager.setCurrentDatabaseItem(
883+
selectedDatabase.databaseItem,
884+
);
885+
}
886+
887+
private async importNewDatabase() {
888+
const importOptions: DatabaseImportQuickPickItems[] = [
889+
{
890+
label: "$(github) GitHub",
891+
detail: "Import a database from a GitHub repository",
892+
alwaysShow: true,
893+
importType: "github",
894+
},
895+
{
896+
label: "$(link) URL",
897+
detail: "Import a database archive or folder from a remote URL",
898+
alwaysShow: true,
899+
importType: "URL",
900+
},
901+
{
902+
label: "$(file-zip) Archive",
903+
detail: "Import a database from a local ZIP archive",
904+
alwaysShow: true,
905+
importType: "archive",
906+
},
907+
{
908+
label: "$(folder) Folder",
909+
detail: "Import a database from a local folder",
910+
alwaysShow: true,
911+
importType: "folder",
912+
},
913+
];
914+
const selectedImportOption =
915+
await window.showQuickPick<DatabaseImportQuickPickItems>(importOptions, {
916+
placeHolder: "Import a database from...",
917+
ignoreFocusOut: true,
918+
});
919+
if (!selectedImportOption) {
920+
throw new UserCancellationException("No database selected", true);
921+
}
922+
if (selectedImportOption.importType === "github") {
923+
await this.handleChooseDatabaseGithub();
924+
} else if (selectedImportOption.importType === "URL") {
925+
await this.handleChooseDatabaseInternet();
926+
} else if (selectedImportOption.importType === "archive") {
927+
await this.handleChooseDatabaseArchive();
928+
} else if (selectedImportOption.importType === "folder") {
929+
await this.handleChooseDatabaseFolder();
930+
}
931+
}
932+
806933
/**
807934
* Ask the user for a database directory. Returns the chosen database, or `undefined` if the
808935
* operation was canceled.

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,7 @@ import type {
33
ProgressUpdate,
44
} from "../common/vscode/progress";
55
import { withProgress } from "../common/vscode/progress";
6-
import type {
7-
CancellationToken,
8-
QuickPickItem,
9-
Range,
10-
TabInputText,
11-
} from "vscode";
6+
import type { CancellationToken, Range, TabInputText } from "vscode";
127
import { CancellationTokenSource, Uri, window } from "vscode";
138
import {
149
TeeLogger,
@@ -23,7 +18,10 @@ import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
2318
import { displayQuickQuery } from "./quick-query";
2419
import type { CoreCompletedQuery, QueryRunner } from "../query-server";
2520
import type { QueryHistoryManager } from "../query-history/query-history-manager";
26-
import type { DatabaseUI } from "../databases/local-databases-ui";
21+
import type {
22+
DatabaseQuickPickItem,
23+
DatabaseUI,
24+
} from "../databases/local-databases-ui";
2725
import type { ResultsView } from "./results-view";
2826
import type {
2927
DatabaseItem,
@@ -55,10 +53,6 @@ import { tryGetQueryLanguage } from "../common/query-language";
5553
import type { LanguageContextStore } from "../language-context-store";
5654
import type { ExtensionApp } from "../common/vscode/vscode-app";
5755

58-
interface DatabaseQuickPickItem extends QuickPickItem {
59-
databaseItem: DatabaseItem;
60-
}
61-
6256
export enum QuickEvalType {
6357
None,
6458
QuickEval,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
export function parseRubyMethodFromPath(path: string): string {
2+
const match = path.match(/Method\[([^\]]+)].*/);
3+
if (match) {
4+
return match[1];
5+
} else {
6+
return "";
7+
}
8+
}
9+
10+
export function parseRubyAccessPath(path: string): {
11+
methodName: string;
12+
path: string;
13+
} {
14+
const match = path.match(/Method\[([^\]]+)]\.(.*)/);
15+
if (match) {
16+
return { methodName: match[1], path: match[2] };
17+
} else {
18+
return { methodName: "", path: "" };
19+
}
20+
}
21+
22+
export function rubyMethodSignature(typeName: string, methodName: string) {
23+
return `${typeName}#${methodName}`;
24+
}
25+
26+
export function rubyMethodPath(methodName: string) {
27+
if (methodName === "") {
28+
return "";
29+
}
30+
31+
return `Method[${methodName}]`;
32+
}
33+
34+
export function rubyPath(methodName: string, path: string) {
35+
const methodPath = rubyMethodPath(methodName);
36+
if (methodPath === "") {
37+
return path;
38+
}
39+
40+
return `${methodPath}.${path}`;
41+
}

0 commit comments

Comments
 (0)