Skip to content

Commit 25b9aeb

Browse files
authored
DB panel: "Add list" command (#1851)
1 parent e521112 commit 25b9aeb

File tree

5 files changed

+113
-5
lines changed

5 files changed

+113
-5
lines changed

extensions/ql-vscode/package.json

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"onCommand:codeQLDatabases.chooseDatabase",
6363
"onCommand:codeQLDatabases.setCurrentDatabase",
6464
"onCommand:codeQLDatabasesExperimental.openConfigFile",
65+
"onCommand:codeQLDatabasesExperimental.addNewList",
6566
"onCommand:codeQLDatabasesExperimental.setSelectedItem",
6667
"onCommand:codeQL.quickQuery",
6768
"onCommand:codeQL.restartQueryServer",
@@ -361,10 +362,12 @@
361362
{
362363
"command": "codeQLDatabasesExperimental.openConfigFile",
363364
"title": "Open Database Configuration File",
364-
"icon": {
365-
"light": "media/light/edit.svg",
366-
"dark": "media/dark/edit.svg"
367-
}
365+
"icon": "$(edit)"
366+
},
367+
{
368+
"command": "codeQLDatabasesExperimental.addNewList",
369+
"title": "Add new list",
370+
"icon": "$(new-folder)"
368371
},
369372
{
370373
"command": "codeQLDatabasesExperimental.setSelectedItem",
@@ -774,6 +777,11 @@
774777
"command": "codeQLDatabasesExperimental.openConfigFile",
775778
"when": "view == codeQLDatabasesExperimental",
776779
"group": "navigation"
780+
},
781+
{
782+
"command": "codeQLDatabasesExperimental.addNewList",
783+
"when": "view == codeQLDatabasesExperimental",
784+
"group": "navigation"
777785
}
778786
],
779787
"view/item/context": [
@@ -997,6 +1005,10 @@
9971005
"command": "codeQLDatabasesExperimental.openConfigFile",
9981006
"when": "false"
9991007
},
1008+
{
1009+
"command": "codeQLDatabasesExperimental.addNewList",
1010+
"when": "false"
1011+
},
10001012
{
10011013
"command": "codeQLDatabasesExperimental.setSelectedItem",
10021014
"when": "false"

extensions/ql-vscode/src/databases/config/db-config-store.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,21 @@ export class DbConfigStore extends DisposableObject {
9090
await this.writeConfig(config);
9191
}
9292

93+
public async addRemoteList(listName: string): Promise<void> {
94+
if (!this.config) {
95+
throw Error("Cannot add remote list if config is not loaded");
96+
}
97+
98+
const config: DbConfig = cloneDbConfig(this.config);
99+
config.databases.remote.repositoryLists.push({
100+
name: listName,
101+
repositories: [],
102+
});
103+
104+
// TODO: validate that the name doesn't already exist
105+
await this.writeConfig(config);
106+
}
107+
93108
private async writeConfig(config: DbConfig): Promise<void> {
94109
await writeJSON(this.configPath, config, {
95110
spaces: 2,

extensions/ql-vscode/src/databases/db-manager.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,8 @@ export class DbManager {
7373

7474
await this.dbConfigStore.updateExpandedState(newExpandedItems);
7575
}
76+
77+
public async addNewRemoteList(listName: string): Promise<void> {
78+
await this.dbConfigStore.addRemoteList(listName);
79+
}
7680
}

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ export class DbPanel extends DisposableObject {
3838
this.openConfigFile(),
3939
),
4040
);
41+
this.push(
42+
commandRunner("codeQLDatabasesExperimental.addNewList", () =>
43+
this.addNewRemoteList(),
44+
),
45+
);
4146
this.push(
4247
commandRunner(
4348
"codeQLDatabasesExperimental.setSelectedItem",
@@ -52,6 +57,18 @@ export class DbPanel extends DisposableObject {
5257
await window.showTextDocument(document);
5358
}
5459

60+
private async addNewRemoteList(): Promise<void> {
61+
// TODO: check that config exists *before* showing the input box
62+
const listName = await window.showInputBox({
63+
prompt: "Enter a name for the new list",
64+
placeHolder: "example-list",
65+
});
66+
if (listName === undefined) {
67+
return;
68+
}
69+
await this.dbManager.addNewRemoteList(listName);
70+
}
71+
5572
private async setSelectedItem(treeViewItem: DbTreeViewItem): Promise<void> {
5673
if (treeViewItem.dbItem === undefined) {
5774
throw new Error(

extensions/ql-vscode/src/vscode-tests/minimal-workspace/databases/db-panel.test.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { TreeItemCollapsibleState, ThemeIcon } from "vscode";
22
import { join } from "path";
3-
import { ensureDir, remove, writeJson } from "fs-extra";
3+
import { ensureDir, readJSON, remove, writeJson } from "fs-extra";
44
import {
55
DbConfig,
66
SelectedDbItemKind,
@@ -531,6 +531,66 @@ describe("db panel", () => {
531531
}
532532
});
533533

534+
it("should add a new list to the remote db list", async () => {
535+
const dbConfig: DbConfig = {
536+
databases: {
537+
remote: {
538+
repositoryLists: [
539+
{
540+
name: "my-list-1",
541+
repositories: ["owner1/repo1", "owner1/repo2"],
542+
},
543+
],
544+
owners: [],
545+
repositories: [],
546+
},
547+
local: {
548+
lists: [],
549+
databases: [],
550+
},
551+
},
552+
expanded: [],
553+
selected: {
554+
kind: SelectedDbItemKind.RemoteUserDefinedList,
555+
listName: "my-list-1",
556+
},
557+
};
558+
559+
await saveDbConfig(dbConfig);
560+
561+
const dbTreeItems = await dbTreeDataProvider.getChildren();
562+
563+
expect(dbTreeItems).toBeTruthy();
564+
const items = dbTreeItems!;
565+
566+
const remoteRootNode = items[0];
567+
const remoteUserDefinedLists = remoteRootNode.children.filter(
568+
(c) => c.dbItem?.kind === DbItemKind.RemoteUserDefinedList,
569+
);
570+
const list1 = remoteRootNode.children.find(
571+
(c) =>
572+
c.dbItem?.kind === DbItemKind.RemoteUserDefinedList &&
573+
c.dbItem?.listName === "my-list-1",
574+
);
575+
576+
expect(remoteUserDefinedLists.length).toBe(1);
577+
expect(remoteUserDefinedLists[0]).toBe(list1);
578+
579+
await dbManager.addNewRemoteList("my-list-2");
580+
581+
// Read the workspace databases JSON file directly to check that the new list has been added.
582+
// We can't use the dbConfigStore's `read` function here because it depends on the file watcher
583+
// picking up changes, and we don't control the timing of that.
584+
const dbConfigFileContents = await readJSON(dbConfigFilePath);
585+
expect(dbConfigFileContents.databases.remote.repositoryLists.length).toBe(
586+
2,
587+
);
588+
expect(dbConfigFileContents.databases.remote.repositoryLists[1]).toEqual({
589+
name: "my-list-2",
590+
repositories: [],
591+
});
592+
});
593+
534594
async function saveDbConfig(dbConfig: DbConfig): Promise<void> {
535595
await writeJson(dbConfigFilePath, dbConfig);
536596

0 commit comments

Comments
 (0)