data workspace extension batch 2 (#12208)

* work in progress

* load projects in view and test cases

* update scope

* make the sql proj menu available in workspace view

* add extension unit test

* address comments

* fix errors
This commit is contained in:
Alan Ren
2020-09-10 17:17:57 -07:00
committed by GitHub
parent cd8102535b
commit 7df132b307
20 changed files with 645 additions and 32 deletions

View File

@@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IProjectProvider, IProjectType } from 'dataworkspace';
import * as vscode from 'vscode';
/**
* Defines the project provider registry
*/
export interface IProjectProviderRegistry {
/**
* Registers a new project provider
* @param provider The project provider
*/
registerProvider(provider: IProjectProvider): vscode.Disposable;
/**
* Clear the providers
*/
clear(): void;
/**
* Gets all the registered providers
*/
readonly providers: IProjectProvider[];
/**
* Gets the project provider for the specified project type
* @param projectType The project type, file extension of the project
*/
getProviderByProjectType(projectType: string): IProjectProvider | undefined;
}
/**
* Defines the project service
*/
export interface IWorkspaceService {
/**
* Gets all supported project types
*/
getAllProjectTypes(): Promise<IProjectType[]>;
/**
* Gets the project files in current workspace
*/
getProjectsInWorkspace(): Promise<string[]>;
/**
* Gets the project provider by project file
* @param projectFilePath The full path of the project file
*/
getProjectProvider(projectFilePath: string): Promise<IProjectProvider | undefined>;
}
/**
* Represents the item for the workspace tree
*/
export interface WorkspaceTreeItem {
/**
* Gets the tree data provider
*/
treeDataProvider: vscode.TreeDataProvider<any>;
/**
* Gets the raw element returned by the tree data provider
*/
element: any;
}

View File

@@ -0,0 +1,12 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export class Log {
error(msg: string): void {
console.error(msg);
}
}
const Logger = new Log();
export default Logger;

View File

@@ -0,0 +1,45 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IProjectProvider } from 'dataworkspace';
import * as vscode from 'vscode';
import { IProjectProviderRegistry } from './interfaces';
export const ProjectProviderRegistry: IProjectProviderRegistry = new class implements IProjectProviderRegistry {
private _providers = new Array<IProjectProvider>();
private _providerMapping: { [key: string]: IProjectProvider } = {};
registerProvider(provider: IProjectProvider): vscode.Disposable {
this.validateProvider(provider);
this._providers.push(provider);
provider.supportedProjectTypes.forEach(projectType => {
this._providerMapping[projectType.projectFileExtension.toUpperCase()] = provider;
});
return new vscode.Disposable(() => {
const idx = this._providers.indexOf(provider);
if (idx >= 0) {
this._providers.splice(idx, 1);
provider.supportedProjectTypes.forEach(projectType => {
delete this._providerMapping[projectType.projectFileExtension.toUpperCase()];
});
}
});
}
get providers(): IProjectProvider[] {
return this._providers.slice(0);
}
clear(): void {
this._providers.length = 0;
}
validateProvider(provider: IProjectProvider): void {
}
getProviderByProjectType(projectType: string): IProjectProvider | undefined {
return projectType ? this._providerMapping[projectType.toUpperCase()] : undefined;
}
};

View File

@@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { IWorkspaceService, WorkspaceTreeItem as WorkspaceTreeItem } from './interfaces';
import * as nls from 'vscode-nls';
import { EOL } from 'os';
const localize = nls.loadMessageBundle();
/**
* Tree data provider for the workspace main view
*/
export class WorkspaceTreeDataProvider implements vscode.TreeDataProvider<WorkspaceTreeItem>{
constructor(private _workspaceService: IWorkspaceService) { }
private _onDidChangeTreeData: vscode.EventEmitter<void | WorkspaceTreeItem | null | undefined> | undefined = new vscode.EventEmitter<WorkspaceTreeItem | undefined | void>();
readonly onDidChangeTreeData?: vscode.Event<void | WorkspaceTreeItem | null | undefined> | undefined = this._onDidChangeTreeData?.event;
refresh(): void {
this._onDidChangeTreeData?.fire();
}
getTreeItem(element: WorkspaceTreeItem): vscode.TreeItem | Thenable<vscode.TreeItem> {
return element.treeDataProvider.getTreeItem(element.element);
}
async getChildren(element?: WorkspaceTreeItem | undefined): Promise<WorkspaceTreeItem[]> {
if (element) {
const items = await element.treeDataProvider.getChildren(element.element);
return items ? items.map(item => <WorkspaceTreeItem>{ treeDataProvider: element.treeDataProvider, element: item }) : [];
}
else {
// if the element is undefined return the project tree items
const projects = await this._workspaceService.getProjectsInWorkspace();
const unknownProjects: string[] = [];
const treeItems: WorkspaceTreeItem[] = [];
let project: string;
for (project of projects) {
const projectProvider = await this._workspaceService.getProjectProvider(project);
if (projectProvider === undefined) {
unknownProjects.push(project);
continue;
}
const treeDataProvider = await projectProvider.getProjectTreeDataProvider(project);
if (treeDataProvider.onDidChangeTreeData) {
treeDataProvider.onDidChangeTreeData((e: any) => {
this._onDidChangeTreeData?.fire(e);
});
}
const children = await treeDataProvider.getChildren(element);
children?.forEach(child => {
treeItems.push({
treeDataProvider: treeDataProvider,
element: child
});
});
}
if (unknownProjects.length > 0) {
vscode.window.showErrorMessage(localize('UnknownProjectsError', "No provider was found for the following projects: {0}", unknownProjects.join(EOL)));
}
return treeItems;
}
}
}