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,76 @@
/*---------------------------------------------------------------------------------------------
* 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 * as dataworkspace from 'dataworkspace';
import * as path from 'path';
import { IWorkspaceService } from '../common/interfaces';
import { ProjectProviderRegistry } from '../common/projectProviderRegistry';
import * as nls from 'vscode-nls';
import Logger from '../common/logger';
const localize = nls.loadMessageBundle();
const WorkspaceConfigurationName = 'dataworkspace';
const ProjectsConfigurationName = 'projects';
export class WorkspaceService implements IWorkspaceService {
async getAllProjectTypes(): Promise<dataworkspace.IProjectType[]> {
await this.ensureProviderExtensionLoaded();
const projectTypes: dataworkspace.IProjectType[] = [];
ProjectProviderRegistry.providers.forEach(provider => {
projectTypes.push(...provider.supportedProjectTypes);
});
return projectTypes;
}
async getProjectsInWorkspace(): Promise<string[]> {
if (vscode.workspace.workspaceFile) {
const projects = <string[]>vscode.workspace.getConfiguration(WorkspaceConfigurationName).get(ProjectsConfigurationName);
return projects.map(project => path.isAbsolute(project) ? project : path.join(vscode.workspace.rootPath!, project));
}
return [];
}
async getProjectProvider(projectFilePath: string): Promise<dataworkspace.IProjectProvider | undefined> {
const projectType = path.extname(projectFilePath).replace(/\./g, '');
let provider = ProjectProviderRegistry.getProviderByProjectType(projectType);
if (!provider) {
await this.ensureProviderExtensionLoaded(projectType);
}
return ProjectProviderRegistry.getProviderByProjectType(projectType);
}
/**
* Ensure the project provider extension for the specified project is loaded
* @param projectType The file extension of the project, if not specified, all project provider extensions will be loaded.
*/
private async ensureProviderExtensionLoaded(projectType: string | undefined = undefined): Promise<void> {
const inactiveExtensions = vscode.extensions.all.filter(ext => !ext.isActive);
const projType = projectType ? projectType.toUpperCase() : undefined;
let extension: vscode.Extension<any>;
for (extension of inactiveExtensions) {
const projectTypes = extension.packageJSON.contributes && extension.packageJSON.contributes.projects as string[];
// Process only when this extension is contributing project providers
if (projectTypes && projectTypes.length > 0) {
if (projType) {
if (projectTypes.findIndex((proj: string) => proj.toUpperCase() === projType) !== -1) {
await this.activateExtension(extension);
break;
}
} else {
await this.activateExtension(extension);
}
}
}
}
private async activateExtension(extension: vscode.Extension<any>): Promise<void> {
try {
await extension.activate();
} catch (err) {
Logger.error(localize('activateExtensionFailed', "Failed to load the project provider extension '{0}'. Error message: {1}", extension.id, err.message ?? err));
}
}
}