mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-27 09:35:37 -05:00
add existing project to workspace feature (#12249)
* add existing project to workspace feature * update file name * new test and use URI * handle workspace with no folder * add more validation * and more tests * use forward slash
This commit is contained in:
@@ -8,14 +8,44 @@ 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';
|
||||
import { ExtensionActivationErrorMessage } from '../common/constants';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
const WorkspaceConfigurationName = 'dataworkspace';
|
||||
const ProjectsConfigurationName = 'projects';
|
||||
|
||||
export class WorkspaceService implements IWorkspaceService {
|
||||
async addProjectsToWorkspace(projectFiles: vscode.Uri[]): Promise<void> {
|
||||
if (vscode.workspace.workspaceFile) {
|
||||
const currentProjects: vscode.Uri[] = await this.getProjectsInWorkspace();
|
||||
const newWorkspaceFolders: string[] = [];
|
||||
let newProjectFileAdded = false;
|
||||
for (const projectFile of projectFiles) {
|
||||
if (currentProjects.findIndex((p: vscode.Uri) => p.fsPath === projectFile.fsPath) === -1) {
|
||||
currentProjects.push(projectFile);
|
||||
newProjectFileAdded = true;
|
||||
|
||||
// if the relativePath and the original path is the same, that means the project file is not under
|
||||
// any workspace folders, we should add the parent folder of the project file to the workspace
|
||||
const relativePath = vscode.workspace.asRelativePath(projectFile, false);
|
||||
if (vscode.Uri.file(relativePath).fsPath === projectFile.fsPath) {
|
||||
newWorkspaceFolders.push(path.dirname(projectFile.path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newProjectFileAdded) {
|
||||
// Save the new set of projects to the workspace configuration.
|
||||
await this.setWorkspaceConfigurationValue(ProjectsConfigurationName, currentProjects.map(project => this.toRelativePath(project)));
|
||||
}
|
||||
|
||||
if (newWorkspaceFolders.length > 0) {
|
||||
// second parameter is null means don't remove any workspace folders
|
||||
vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders!.length, null, ...(newWorkspaceFolders.map(folder => ({ uri: vscode.Uri.file(folder) }))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async getAllProjectTypes(): Promise<dataworkspace.IProjectType[]> {
|
||||
await this.ensureProviderExtensionLoaded();
|
||||
const projectTypes: dataworkspace.IProjectType[] = [];
|
||||
@@ -25,16 +55,12 @@ export class WorkspaceService implements IWorkspaceService {
|
||||
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 getProjectsInWorkspace(): Promise<vscode.Uri[]> {
|
||||
return vscode.workspace.workspaceFile ? this.getWorkspaceConfigurationValue<string[]>(ProjectsConfigurationName).map(project => this.toUri(project)) : [];
|
||||
}
|
||||
|
||||
async getProjectProvider(projectFilePath: string): Promise<dataworkspace.IProjectProvider | undefined> {
|
||||
const projectType = path.extname(projectFilePath).replace(/\./g, '');
|
||||
async getProjectProvider(projectFile: vscode.Uri): Promise<dataworkspace.IProjectProvider | undefined> {
|
||||
const projectType = path.extname(projectFile.path).replace(/\./g, '');
|
||||
let provider = ProjectProviderRegistry.getProviderByProjectType(projectType);
|
||||
if (!provider) {
|
||||
await this.ensureProviderExtensionLoaded(projectType);
|
||||
@@ -70,7 +96,32 @@ export class WorkspaceService implements IWorkspaceService {
|
||||
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));
|
||||
Logger.error(ExtensionActivationErrorMessage(extension.id, err));
|
||||
}
|
||||
}
|
||||
|
||||
getWorkspaceConfigurationValue<T>(configurationName: string): T {
|
||||
return vscode.workspace.getConfiguration(WorkspaceConfigurationName).get(configurationName) as T;
|
||||
}
|
||||
|
||||
async setWorkspaceConfigurationValue(configurationName: string, value: any): Promise<void> {
|
||||
await vscode.workspace.getConfiguration(WorkspaceConfigurationName).update(configurationName, value, vscode.ConfigurationTarget.Workspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the relative path to the workspace file
|
||||
* @param filePath the absolute path
|
||||
*/
|
||||
private toRelativePath(filePath: vscode.Uri): string {
|
||||
return path.relative(path.dirname(vscode.workspace.workspaceFile!.path!), filePath.path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Uri of the given relative path
|
||||
* @param relativePath the relative path
|
||||
*/
|
||||
private toUri(relativePath: string): vscode.Uri {
|
||||
const fullPath = path.join(path.dirname(vscode.workspace.workspaceFile!.path!), relativePath);
|
||||
return vscode.Uri.file(fullPath);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user