Implement addNewDatabase

This commit is contained in:
Nora
2022-12-20 10:48:53 +00:00
parent 6350ac7f66
commit f332e6145a
4 changed files with 138 additions and 2 deletions

View File

@@ -60,6 +60,7 @@
"onCommand:codeQLDatabases.chooseDatabase",
"onCommand:codeQLDatabases.setCurrentDatabase",
"onCommand:codeQLDatabasesExperimental.openConfigFile",
"onCommand:codeQLDatabasesExperimental.addNewDatabase",
"onCommand:codeQLDatabasesExperimental.addNewList",
"onCommand:codeQLDatabasesExperimental.setSelectedItem",
"onCommand:codeQL.quickQuery",
@@ -362,6 +363,11 @@
"title": "Open Database Configuration File",
"icon": "$(edit)"
},
{
"command": "codeQLDatabasesExperimental.addNewDatabase",
"title": "Add new database",
"icon": "$(add)"
},
{
"command": "codeQLDatabasesExperimental.addNewList",
"title": "Add new list",
@@ -759,6 +765,11 @@
"when": "view == codeQLDatabasesExperimental",
"group": "navigation"
},
{
"command": "codeQLDatabasesExperimental.addNewDatabase",
"when": "view == codeQLDatabasesExperimental && codeQLDatabasesExperimental.configError == false",
"group": "navigation"
},
{
"command": "codeQLDatabasesExperimental.addNewList",
"when": "view == codeQLDatabasesExperimental && codeQLDatabasesExperimental.configError == false",
@@ -982,6 +993,10 @@
"command": "codeQLDatabasesExperimental.openConfigFile",
"when": "false"
},
{
"command": "codeQLDatabasesExperimental.addNewDatabase",
"when": "false"
},
{
"command": "codeQLDatabasesExperimental.addNewList",
"when": "false"

View File

@@ -94,6 +94,28 @@ export class DbConfigStore extends DisposableObject {
await this.writeConfig(config);
}
public async addRemoteRepo(repoNwo: string): Promise<void> {
if (!this.config) {
throw Error("Cannot add remote repo if config is not loaded");
}
const config: DbConfig = cloneDbConfig(this.config);
config.databases.remote.repositories.push(repoNwo);
await this.writeConfig(config);
}
public async addRemoteOwner(owner: string): Promise<void> {
if (!this.config) {
throw Error("Cannot add remote owner if config is not loaded");
}
const config: DbConfig = cloneDbConfig(this.config);
config.databases.remote.owners.push(owner);
await this.writeConfig(config);
}
public async addRemoteList(listName: string): Promise<void> {
if (!this.config) {
throw Error("Cannot add remote list if config is not loaded");

View File

@@ -75,6 +75,14 @@ export class DbManager {
await this.dbConfigStore.updateExpandedState(newExpandedItems);
}
public async addNewRemoteRepo(nwo: string): Promise<void> {
await this.dbConfigStore.addRemoteRepo(nwo);
}
public async addNewRemoteOwner(owner: string): Promise<void> {
await this.dbConfigStore.addRemoteOwner(owner);
}
public async addNewRemoteList(listName: string): Promise<void> {
if (listName === "") {
throw Error("List name cannot be empty");

View File

@@ -1,11 +1,26 @@
import { TreeViewExpansionEvent, window, workspace } from "vscode";
import { commandRunner } from "../../commandRunner";
import {
QuickPickItem,
TreeViewExpansionEvent,
window,
workspace,
} from "vscode";
import { commandRunner, UserCancellationException } from "../../commandRunner";
import {
getNwoFromGitHubUrl,
validGitHubNwo,
getOwnerFromGitHubUrl,
validGitHubOwner,
} from "../../common/github-url-identifier-helper";
import { showAndLogErrorMessage } from "../../helpers";
import { DisposableObject } from "../../pure/disposable-object";
import { DbManager } from "../db-manager";
import { DbTreeDataProvider } from "./db-tree-data-provider";
import { DbTreeViewItem } from "./db-tree-view-item";
interface RemoteDatabaseQuickPickItem extends QuickPickItem {
kind: string;
}
export class DbPanel extends DisposableObject {
private readonly dataProvider: DbTreeDataProvider;
@@ -39,6 +54,11 @@ export class DbPanel extends DisposableObject {
this.openConfigFile(),
),
);
this.push(
commandRunner("codeQLDatabasesExperimental.addNewDatabase", () =>
this.addNewRemoteDatabase(),
),
);
this.push(
commandRunner("codeQLDatabasesExperimental.addNewList", () =>
this.addNewRemoteList(),
@@ -58,6 +78,77 @@ export class DbPanel extends DisposableObject {
await window.showTextDocument(document);
}
private async addNewRemoteDatabase(): Promise<void> {
const quickPickItems = [
{
label: "$(repo) From a GitHub repository",
detail: "Add a remote repository from GitHub",
alwaysShow: true,
kind: "repo",
},
{
label: "$(organization) All repositories of a GitHub org or owner",
detail:
"Add a remote list of repositories from a GitHub organization/owner",
alwaysShow: true,
kind: "owner",
},
];
const databaseKind =
await window.showQuickPick<RemoteDatabaseQuickPickItem>(quickPickItems, {
title: "Add a remote repository",
placeHolder: "Select an option",
ignoreFocusOut: true,
});
if (!databaseKind) {
// We don't need to display a warning pop-up in this case, since the user just escaped out of the operation.
// We set 'true' to make this a silent exception.
throw new UserCancellationException("No repository selected", true);
}
if (databaseKind.kind === "repo") {
await this.addNewRemoteRepo();
} else if (databaseKind.kind === "owner") {
await this.addNewRemoteOwner();
}
}
private async addNewRemoteRepo(): Promise<void> {
const repoName = await window.showInputBox({
title: "Add a remote repository",
prompt: "Insert a GitHub repository URL or name with owner",
placeHolder: "github.com/<owner>/<repo> or <owner>/<repo>",
});
if (!repoName) {
return;
}
const nwo = getNwoFromGitHubUrl(repoName) || repoName;
if (!validGitHubNwo(nwo)) {
throw new Error(`Invalid GitHub repository: ${repoName}`);
}
await this.dbManager.addNewRemoteRepo(nwo);
}
private async addNewRemoteOwner(): Promise<void> {
const ownerName = await window.showInputBox({
title: "Add all repositories of a GitHub org or owner",
prompt: "Insert a GitHub organization or owner name",
placeHolder: "github.com/<owner> or <owner>",
});
if (!ownerName) {
return;
}
const owner = getOwnerFromGitHubUrl(ownerName) || ownerName;
if (!validGitHubOwner(owner)) {
throw new Error(`Invalid user or organization: ${owner}`);
}
await this.dbManager.addNewRemoteOwner(owner);
}
private async addNewRemoteList(): Promise<void> {
const listName = await window.showInputBox({
prompt: "Enter a name for the new list",