Skip to content

Commit 0902e18

Browse files
authored
Add context menu command to open repo/owner on GitHub (github#1921)
1 parent 35a49b0 commit 0902e18

File tree

4 files changed

+99
-1
lines changed

4 files changed

+99
-1
lines changed

extensions/ql-vscode/package.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"onCommand:codeQLDatabasesExperimental.addNewList",
6565
"onCommand:codeQLDatabasesExperimental.setSelectedItem",
6666
"onCommand:codeQLDatabasesExperimental.setSelectedItemContextMenu",
67+
"onCommand:codeQLDatabasesExperimental.openOnGitHubContextMenu",
6768
"onCommand:codeQL.quickQuery",
6869
"onCommand:codeQL.restartQueryServer",
6970
"onWebviewPanel:resultsView",
@@ -382,6 +383,10 @@
382383
"command": "codeQLDatabasesExperimental.setSelectedItemContextMenu",
383384
"title": "Select"
384385
},
386+
{
387+
"command": "codeQLDatabasesExperimental.openOnGitHubContextMenu",
388+
"title": "Open on GitHub"
389+
},
385390
{
386391
"command": "codeQLDatabases.chooseDatabaseFolder",
387392
"title": "Choose Database from Folder",
@@ -785,6 +790,10 @@
785790
"command": "codeQLDatabasesExperimental.setSelectedItemContextMenu",
786791
"when": "view == codeQLDatabasesExperimental && viewItem =~ /canBeSelected/"
787792
},
793+
{
794+
"command": "codeQLDatabasesExperimental.openOnGitHubContextMenu",
795+
"when": "view == codeQLDatabasesExperimental && viewItem =~ /canBeOpenedOnGitHub/"
796+
},
788797
{
789798
"command": "codeQLDatabases.setCurrentDatabase",
790799
"group": "inline",
@@ -1017,6 +1026,10 @@
10171026
"command": "codeQLDatabasesExperimental.setSelectedItemContextMenu",
10181027
"when": "false"
10191028
},
1029+
{
1030+
"command": "codeQLDatabasesExperimental.openOnGitHubContextMenu",
1031+
"when": "false"
1032+
},
10201033
{
10211034
"command": "codeQLDatabases.setCurrentDatabase",
10221035
"when": "false"

extensions/ql-vscode/src/databases/ui/db-panel.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import {
2+
commands,
23
QuickPickItem,
34
TreeView,
45
TreeViewExpansionEvent,
6+
Uri,
57
window,
68
workspace,
79
} from "vscode";
@@ -18,6 +20,7 @@ import { DbItem, DbItemKind, DbListKind, remoteDbKinds } from "../db-item";
1820
import { DbManager } from "../db-manager";
1921
import { DbTreeDataProvider } from "./db-tree-data-provider";
2022
import { DbTreeViewItem } from "./db-tree-view-item";
23+
import { getGitHubUrl } from "./db-tree-view-item-action";
2124

2225
export interface RemoteDatabaseQuickPickItem extends QuickPickItem {
2326
kind: string;
@@ -83,6 +86,12 @@ export class DbPanel extends DisposableObject {
8386
(treeViewItem: DbTreeViewItem) => this.setSelectedItem(treeViewItem),
8487
),
8588
);
89+
this.push(
90+
commandRunner(
91+
"codeQLDatabasesExperimental.openOnGitHubContextMenu",
92+
(treeViewItem: DbTreeViewItem) => this.openOnGitHub(treeViewItem),
93+
),
94+
);
8695
}
8796

8897
private async openConfigFile(): Promise<void> {
@@ -290,4 +299,18 @@ export class DbPanel extends DisposableObject {
290299
// You can only select one item at a time, so selection[0] gives the selection
291300
return this.treeView.selection[0]?.dbItem;
292301
}
302+
303+
private async openOnGitHub(treeViewItem: DbTreeViewItem): Promise<void> {
304+
if (treeViewItem.dbItem === undefined) {
305+
throw new Error("Unable to open on GitHub. Please select a valid item.");
306+
}
307+
const githubUrl = getGitHubUrl(treeViewItem.dbItem);
308+
if (!githubUrl) {
309+
throw new Error(
310+
"Unable to open on GitHub. Please select a remote repository or owner.",
311+
);
312+
}
313+
314+
await commands.executeCommand("vscode.open", Uri.parse(githubUrl));
315+
}
293316
}

extensions/ql-vscode/src/databases/ui/db-tree-view-item-action.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,14 @@ function canBeRenamed(dbItem: DbItem): boolean {
5959
function canBeOpenedOnGitHub(dbItem: DbItem): boolean {
6060
return dbItemKindsThatCanBeOpenedOnGitHub.includes(dbItem.kind);
6161
}
62+
63+
export function getGitHubUrl(dbItem: DbItem): string | undefined {
64+
switch (dbItem.kind) {
65+
case DbItemKind.RemoteOwner:
66+
return `https://github.com/${dbItem.ownerName}`;
67+
case DbItemKind.RemoteRepo:
68+
return `https://github.com/${dbItem.repoFullName}`;
69+
default:
70+
return undefined;
71+
}
72+
}

extensions/ql-vscode/test/unit-tests/databases/ui/db-tree-view-item-action.test.ts

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { getDbItemActions } from "../../../../src/databases/ui/db-tree-view-item-action";
1+
import {
2+
getDbItemActions,
3+
getGitHubUrl,
4+
} from "../../../../src/databases/ui/db-tree-view-item-action";
25
import {
36
createLocalDatabaseDbItem,
47
createLocalListDbItem,
@@ -107,3 +110,51 @@ describe("getDbItemActions", () => {
107110
expect(actions.includes("canBeSelected")).toBeFalsy();
108111
});
109112
});
113+
114+
describe("getGitHubUrl", () => {
115+
it("should return the correct url for a remote owner", () => {
116+
const dbItem = createRemoteOwnerDbItem();
117+
118+
const actualUrl = getGitHubUrl(dbItem);
119+
const expectedUrl = `https://github.com/${dbItem.ownerName}`;
120+
121+
expect(actualUrl).toEqual(expectedUrl);
122+
});
123+
124+
it("should return the correct url for a remote repo", () => {
125+
const dbItem = createRemoteRepoDbItem();
126+
127+
const actualUrl = getGitHubUrl(dbItem);
128+
const expectedUrl = `https://github.com/${dbItem.repoFullName}`;
129+
130+
expect(actualUrl).toEqual(expectedUrl);
131+
});
132+
133+
it("should return undefined for other remote db items", () => {
134+
const dbItem0 = createRootRemoteDbItem();
135+
const dbItem1 = createRemoteSystemDefinedListDbItem();
136+
const dbItem2 = createRemoteUserDefinedListDbItem();
137+
138+
const actualUrl0 = getGitHubUrl(dbItem0);
139+
const actualUrl1 = getGitHubUrl(dbItem1);
140+
const actualUrl2 = getGitHubUrl(dbItem2);
141+
142+
expect(actualUrl0).toBeUndefined();
143+
expect(actualUrl1).toBeUndefined();
144+
expect(actualUrl2).toBeUndefined();
145+
});
146+
147+
it("should return undefined for local db items", () => {
148+
const dbItem0 = createRootLocalDbItem();
149+
const dbItem1 = createLocalDatabaseDbItem();
150+
const dbItem2 = createLocalListDbItem();
151+
152+
const actualUrl0 = getGitHubUrl(dbItem0);
153+
const actualUrl1 = getGitHubUrl(dbItem1);
154+
const actualUrl2 = getGitHubUrl(dbItem2);
155+
156+
expect(actualUrl0).toBeUndefined();
157+
expect(actualUrl1).toBeUndefined();
158+
expect(actualUrl2).toBeUndefined();
159+
});
160+
});

0 commit comments

Comments
 (0)