Skip to content

Commit 46a54a6

Browse files
authored
Merge pull request #1900 from github/nora/add-repo-to-list
Add new repositories to a highlighted user defined list
2 parents 25dd679 + 824f56d commit 46a54a6

4 files changed

Lines changed: 152 additions & 37 deletions

File tree

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,10 @@ export class DbConfigStore extends DisposableObject {
9494
await this.writeConfig(config);
9595
}
9696

97-
public async addRemoteRepo(repoNwo: string): Promise<void> {
97+
public async addRemoteRepo(
98+
repoNwo: string,
99+
parentList?: string,
100+
): Promise<void> {
98101
if (!this.config) {
99102
throw Error("Cannot add remote repo if config is not loaded");
100103
}
@@ -110,8 +113,18 @@ export class DbConfigStore extends DisposableObject {
110113
}
111114

112115
const config: DbConfig = cloneDbConfig(this.config);
113-
config.databases.remote.repositories.push(repoNwo);
114-
116+
if (parentList) {
117+
const parent = config.databases.remote.repositoryLists.find(
118+
(list) => list.name === parentList,
119+
);
120+
if (!parent) {
121+
throw Error(`Cannot find parent list '${parentList}'`);
122+
} else {
123+
parent.repositories.push(repoNwo);
124+
}
125+
} else {
126+
config.databases.remote.repositories.push(repoNwo);
127+
}
115128
await this.writeConfig(config);
116129
}
117130

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,11 @@ export class DbManager {
7575
await this.dbConfigStore.updateExpandedState(newExpandedItems);
7676
}
7777

78-
public async addNewRemoteRepo(nwo: string): Promise<void> {
79-
await this.dbConfigStore.addRemoteRepo(nwo);
78+
public async addNewRemoteRepo(
79+
nwo: string,
80+
parentList?: string,
81+
): Promise<void> {
82+
await this.dbConfigStore.addRemoteRepo(nwo, parentList);
8083
}
8184

8285
public async addNewRemoteOwner(owner: string): Promise<void> {

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

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -82,40 +82,54 @@ export class DbPanel extends DisposableObject {
8282
}
8383

8484
private async addNewRemoteDatabase(): Promise<void> {
85-
const quickPickItems = [
86-
{
87-
label: "$(repo) From a GitHub repository",
88-
detail: "Add a remote repository from GitHub",
89-
alwaysShow: true,
90-
kind: "repo",
91-
},
92-
{
93-
label: "$(organization) All repositories of a GitHub org or owner",
94-
detail:
95-
"Add a remote list of repositories from a GitHub organization/owner",
96-
alwaysShow: true,
97-
kind: "owner",
98-
},
99-
];
100-
const databaseKind =
101-
await window.showQuickPick<RemoteDatabaseQuickPickItem>(quickPickItems, {
102-
title: "Add a remote repository",
103-
placeHolder: "Select an option",
104-
ignoreFocusOut: true,
105-
});
106-
if (!databaseKind) {
107-
// We don't need to display a warning pop-up in this case, since the user just escaped out of the operation.
108-
// We set 'true' to make this a silent exception.
109-
throw new UserCancellationException("No repository selected", true);
110-
}
111-
if (databaseKind.kind === "repo") {
112-
await this.addNewRemoteRepo();
113-
} else if (databaseKind.kind === "owner") {
114-
await this.addNewRemoteOwner();
85+
const highlightedItem = await this.getHighlightedDbItem();
86+
87+
if (highlightedItem?.kind === DbItemKind.RemoteUserDefinedList) {
88+
await this.addNewRemoteRepo(highlightedItem.listName);
89+
} else if (
90+
highlightedItem?.kind === DbItemKind.RemoteRepo &&
91+
highlightedItem.parentListName
92+
) {
93+
await this.addNewRemoteRepo(highlightedItem.parentListName);
94+
} else {
95+
const quickPickItems = [
96+
{
97+
label: "$(repo) From a GitHub repository",
98+
detail: "Add a remote repository from GitHub",
99+
alwaysShow: true,
100+
kind: "repo",
101+
},
102+
{
103+
label: "$(organization) All repositories of a GitHub org or owner",
104+
detail:
105+
"Add a remote list of repositories from a GitHub organization/owner",
106+
alwaysShow: true,
107+
kind: "owner",
108+
},
109+
];
110+
const databaseKind =
111+
await window.showQuickPick<RemoteDatabaseQuickPickItem>(
112+
quickPickItems,
113+
{
114+
title: "Add a remote repository",
115+
placeHolder: "Select an option",
116+
ignoreFocusOut: true,
117+
},
118+
);
119+
if (!databaseKind) {
120+
// We don't need to display a warning pop-up in this case, since the user just escaped out of the operation.
121+
// We set 'true' to make this a silent exception.
122+
throw new UserCancellationException("No repository selected", true);
123+
}
124+
if (databaseKind.kind === "repo") {
125+
await this.addNewRemoteRepo();
126+
} else if (databaseKind.kind === "owner") {
127+
await this.addNewRemoteOwner();
128+
}
115129
}
116130
}
117131

118-
private async addNewRemoteRepo(): Promise<void> {
132+
private async addNewRemoteRepo(parentList?: string): Promise<void> {
119133
const repoName = await window.showInputBox({
120134
title: "Add a remote repository",
121135
prompt: "Insert a GitHub repository URL or name with owner",
@@ -136,7 +150,7 @@ export class DbPanel extends DisposableObject {
136150
return;
137151
}
138152

139-
await this.dbManager.addNewRemoteRepo(nwo);
153+
await this.dbManager.addNewRemoteRepo(nwo, parentList);
140154
}
141155

142156
private async addNewRemoteOwner(): Promise<void> {

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

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,91 @@ describe("db panel", () => {
447447
}
448448
});
449449

450+
describe("addNewRemoteRepo", () => {
451+
it("should add a new remote repo", async () => {
452+
const dbConfig: DbConfig = createDbConfig({
453+
remoteRepos: ["owner1/repo1"],
454+
});
455+
456+
await saveDbConfig(dbConfig);
457+
458+
const dbTreeItems = await dbTreeDataProvider.getChildren();
459+
460+
expect(dbTreeItems).toBeTruthy();
461+
const items = dbTreeItems!;
462+
463+
const remoteRootNode = items[0];
464+
const remoteRepos = remoteRootNode.children.filter(
465+
(c) => c.dbItem?.kind === DbItemKind.RemoteRepo,
466+
);
467+
const repo1 = remoteRootNode.children.find(
468+
(c) =>
469+
c.dbItem?.kind === DbItemKind.RemoteRepo &&
470+
c.dbItem?.repoFullName === "owner1/repo1",
471+
);
472+
473+
expect(remoteRepos.length).toBe(1);
474+
expect(remoteRepos[0]).toBe(repo1);
475+
476+
await dbManager.addNewRemoteRepo("owner2/repo2");
477+
478+
// Read the workspace databases JSON file directly to check that the new repo has been added.
479+
// We can't use the dbConfigStore's `read` function here because it depends on the file watcher
480+
// picking up changes, and we don't control the timing of that.
481+
const dbConfigFileContents = await readJSON(dbConfigFilePath);
482+
expect(dbConfigFileContents.databases.remote.repositories.length).toBe(2);
483+
expect(dbConfigFileContents.databases.remote.repositories[1]).toEqual(
484+
"owner2/repo2",
485+
);
486+
});
487+
488+
it("should add a new remote repo to a user defined list", async () => {
489+
const dbConfig: DbConfig = createDbConfig({
490+
remoteLists: [
491+
{
492+
name: "my-list-1",
493+
repositories: ["owner1/repo1"],
494+
},
495+
],
496+
});
497+
498+
await saveDbConfig(dbConfig);
499+
500+
const dbTreeItems = await dbTreeDataProvider.getChildren();
501+
502+
expect(dbTreeItems).toBeTruthy();
503+
const items = dbTreeItems!;
504+
505+
const remoteRootNode = items[0];
506+
const remoteUserDefinedLists = remoteRootNode.children.filter(
507+
(c) => c.dbItem?.kind === DbItemKind.RemoteUserDefinedList,
508+
);
509+
const list1 = remoteRootNode.children.find(
510+
(c) =>
511+
c.dbItem?.kind === DbItemKind.RemoteUserDefinedList &&
512+
c.dbItem?.listName === "my-list-1",
513+
);
514+
515+
expect(remoteUserDefinedLists.length).toBe(1);
516+
expect(remoteUserDefinedLists[0]).toBe(list1);
517+
518+
await dbManager.addNewRemoteRepo("owner2/repo2", "my-list-1");
519+
520+
// Read the workspace databases JSON file directly to check that the new repo has been added.
521+
// We can't use the dbConfigStore's `read` function here because it depends on the file watcher
522+
// picking up changes, and we don't control the timing of that.
523+
const dbConfigFileContents = await readJSON(dbConfigFilePath);
524+
expect(dbConfigFileContents.databases.remote.repositoryLists.length).toBe(
525+
1,
526+
);
527+
528+
expect(dbConfigFileContents.databases.remote.repositoryLists[0]).toEqual({
529+
name: "my-list-1",
530+
repositories: ["owner1/repo1", "owner2/repo2"],
531+
});
532+
});
533+
});
534+
450535
describe("addNewList", () => {
451536
it("should add a new remote list", async () => {
452537
const dbConfig: DbConfig = createDbConfig({

0 commit comments

Comments
 (0)