Merge pull request #1889 from github/shati-nora/add-remote-repositories
Create "Add database" button in DB panel
This commit is contained in:
@@ -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",
|
||||
@@ -758,6 +764,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",
|
||||
@@ -981,6 +992,10 @@
|
||||
"command": "codeQLDatabasesExperimental.openConfigFile",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "codeQLDatabasesExperimental.addNewDatabase",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "codeQLDatabasesExperimental.addNewList",
|
||||
"when": "false"
|
||||
|
||||
@@ -5,7 +5,7 @@ import { OWNER_REGEX, REPO_REGEX } from "../pure/helpers-pure";
|
||||
* @param identifier The GitHub NWO
|
||||
* @returns
|
||||
*/
|
||||
export function validGitHubNwo(identifier: string): boolean {
|
||||
export function isValidGitHubNwo(identifier: string): boolean {
|
||||
return validGitHubNwoOrOwner(identifier, "nwo");
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export function validGitHubNwo(identifier: string): boolean {
|
||||
* @param identifier The GitHub owner
|
||||
* @returns
|
||||
*/
|
||||
export function validGitHubOwner(identifier: string): boolean {
|
||||
export function isValidGitHubOwner(identifier: string): boolean {
|
||||
return validGitHubNwoOrOwner(identifier, "owner");
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ function validGitHubNwoOrOwner(
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts an NOW from a GitHub URL.
|
||||
* Extracts an NWO from a GitHub URL.
|
||||
* @param githubUrl The GitHub repository URL
|
||||
* @return The corresponding NWO, or undefined if the URL is not valid
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,7 @@ import { Credentials } from "./authentication";
|
||||
import { getErrorMessage } from "./pure/helpers-pure";
|
||||
import {
|
||||
getNwoFromGitHubUrl,
|
||||
validGitHubNwo,
|
||||
isValidGitHubNwo,
|
||||
} from "./common/github-url-identifier-helper";
|
||||
|
||||
/**
|
||||
@@ -101,7 +101,7 @@ export async function promptImportGithubDatabase(
|
||||
}
|
||||
|
||||
const nwo = getNwoFromGitHubUrl(githubRepo) || githubRepo;
|
||||
if (!validGitHubNwo(nwo)) {
|
||||
if (!isValidGitHubNwo(nwo)) {
|
||||
throw new Error(`Invalid GitHub repository: ${githubRepo}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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 addNewList(kind: DbItemKind, listName: string): Promise<void> {
|
||||
if (remoteDbKinds.includes(kind)) {
|
||||
if (listName === "") {
|
||||
|
||||
@@ -1,11 +1,27 @@
|
||||
import { TreeView, TreeViewExpansionEvent, window, workspace } from "vscode";
|
||||
import { commandRunner } from "../../commandRunner";
|
||||
import {
|
||||
QuickPickItem,
|
||||
TreeView,
|
||||
TreeViewExpansionEvent,
|
||||
window,
|
||||
workspace,
|
||||
} from "vscode";
|
||||
import { commandRunner, UserCancellationException } from "../../commandRunner";
|
||||
import {
|
||||
getNwoFromGitHubUrl,
|
||||
isValidGitHubNwo,
|
||||
getOwnerFromGitHubUrl,
|
||||
isValidGitHubOwner,
|
||||
} from "../../common/github-url-identifier-helper";
|
||||
import { DisposableObject } from "../../pure/disposable-object";
|
||||
import { DbItem, DbItemKind } from "../db-item";
|
||||
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;
|
||||
private readonly treeView: TreeView<DbTreeViewItem>;
|
||||
@@ -40,6 +56,11 @@ export class DbPanel extends DisposableObject {
|
||||
this.openConfigFile(),
|
||||
),
|
||||
);
|
||||
this.push(
|
||||
commandRunner("codeQLDatabasesExperimental.addNewDatabase", () =>
|
||||
this.addNewRemoteDatabase(),
|
||||
),
|
||||
);
|
||||
this.push(
|
||||
commandRunner("codeQLDatabasesExperimental.addNewList", () =>
|
||||
this.addNewRemoteList(),
|
||||
@@ -59,6 +80,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 (!isValidGitHubNwo(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 (!isValidGitHubOwner(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",
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import {
|
||||
getNwoFromGitHubUrl,
|
||||
getOwnerFromGitHubUrl,
|
||||
validGitHubNwo,
|
||||
validGitHubOwner,
|
||||
isValidGitHubNwo,
|
||||
isValidGitHubOwner,
|
||||
} from "../../../src/common/github-url-identifier-helper";
|
||||
|
||||
describe("github url identifier helper", () => {
|
||||
describe("valid GitHub Nwo Or Owner method", () => {
|
||||
it("should return true for valid owner", () => {
|
||||
expect(validGitHubOwner("github")).toBe(true);
|
||||
expect(isValidGitHubOwner("github")).toBe(true);
|
||||
});
|
||||
it("should return true for valid NWO", () => {
|
||||
expect(validGitHubNwo("github/codeql")).toBe(true);
|
||||
expect(isValidGitHubNwo("github/codeql")).toBe(true);
|
||||
});
|
||||
it("should return false for invalid owner", () => {
|
||||
expect(validGitHubOwner("github/codeql")).toBe(false);
|
||||
expect(isValidGitHubOwner("github/codeql")).toBe(false);
|
||||
});
|
||||
it("should return false for invalid NWO", () => {
|
||||
expect(validGitHubNwo("githubl")).toBe(false);
|
||||
expect(isValidGitHubNwo("githubl")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user