mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-31 17:23:31 -05:00
Vscode merge (#4582)
* Merge from vscode 37cb23d3dd4f9433d56d4ba5ea3203580719a0bd * fix issues with merges * bump node version in azpipe * replace license headers * remove duplicate launch task * fix build errors * fix build errors * fix tslint issues * working through package and linux build issues * more work * wip * fix packaged builds * working through linux build errors * wip * wip * wip * fix mac and linux file limits * iterate linux pipeline * disable editor typing * revert series to parallel * remove optimize vscode from linux * fix linting issues * revert testing change * add work round for new node * readd packaging for extensions * fix issue with angular not resolving decorator dependencies
This commit is contained in:
@@ -7,7 +7,15 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
|
||||
import { localize } from 'vs/nls';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform';
|
||||
import { extname } from 'vs/base/common/path';
|
||||
import { dirname, resolvePath, isEqualAuthority, isEqualOrParent, relativePath } from 'vs/base/common/resources';
|
||||
import * as jsonEdit from 'vs/base/common/jsonEdit';
|
||||
import * as json from 'vs/base/common/json';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { normalizeDriveLetter } from 'vs/base/common/labels';
|
||||
import { toSlashes } from 'vs/base/common/extpath';
|
||||
|
||||
export const IWorkspacesMainService = createDecorator<IWorkspacesMainService>('workspacesMainService');
|
||||
export const IWorkspacesService = createDecorator<IWorkspacesService>('workspacesService');
|
||||
@@ -23,7 +31,11 @@ export type ISingleFolderWorkspaceIdentifier = URI;
|
||||
|
||||
export interface IWorkspaceIdentifier {
|
||||
id: string;
|
||||
configPath: string;
|
||||
configPath: URI;
|
||||
}
|
||||
|
||||
export function reviveWorkspaceIdentifier(workspace: { id: string, configPath: UriComponents; }): IWorkspaceIdentifier {
|
||||
return { id: workspace.id, configPath: URI.revive(workspace.configPath) };
|
||||
}
|
||||
|
||||
export function isStoredWorkspaceFolder(thing: any): thing is IStoredWorkspaceFolder {
|
||||
@@ -58,6 +70,7 @@ export type IStoredWorkspaceFolder = IRawFileWorkspaceFolder | IRawUriWorkspaceF
|
||||
|
||||
export interface IResolvedWorkspace extends IWorkspaceIdentifier {
|
||||
folders: IWorkspaceFolder[];
|
||||
remoteAuthority?: string;
|
||||
}
|
||||
|
||||
export interface IStoredWorkspace {
|
||||
@@ -74,32 +87,35 @@ export interface IWorkspaceFolderCreationData {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export interface IUntitledWorkspaceInfo {
|
||||
workspace: IWorkspaceIdentifier;
|
||||
remoteAuthority?: string;
|
||||
}
|
||||
|
||||
export interface IWorkspacesMainService extends IWorkspacesService {
|
||||
_serviceBrand: any;
|
||||
|
||||
onUntitledWorkspaceDeleted: Event<IWorkspaceIdentifier>;
|
||||
|
||||
saveWorkspaceAs(workspace: IWorkspaceIdentifier, target: string): Promise<IWorkspaceIdentifier>;
|
||||
|
||||
createUntitledWorkspaceSync(folders?: IWorkspaceFolderCreationData[]): IWorkspaceIdentifier;
|
||||
|
||||
resolveWorkspaceSync(path: string): IResolvedWorkspace | null;
|
||||
resolveLocalWorkspaceSync(path: URI): IResolvedWorkspace | null;
|
||||
|
||||
isUntitledWorkspace(workspace: IWorkspaceIdentifier): boolean;
|
||||
|
||||
deleteUntitledWorkspaceSync(workspace: IWorkspaceIdentifier): void;
|
||||
|
||||
getUntitledWorkspacesSync(): IWorkspaceIdentifier[];
|
||||
|
||||
getWorkspaceId(workspacePath: string): string;
|
||||
|
||||
getWorkspaceIdentifier(workspacePath: URI): IWorkspaceIdentifier;
|
||||
getUntitledWorkspacesSync(): IUntitledWorkspaceInfo[];
|
||||
}
|
||||
|
||||
export interface IWorkspacesService {
|
||||
_serviceBrand: any;
|
||||
|
||||
createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[]): Promise<IWorkspaceIdentifier>;
|
||||
createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise<IWorkspaceIdentifier>;
|
||||
|
||||
deleteUntitledWorkspace(workspace: IWorkspaceIdentifier): Promise<void>;
|
||||
|
||||
getWorkspaceIdentifier(workspacePath: URI): Promise<IWorkspaceIdentifier>;
|
||||
}
|
||||
|
||||
export function isSingleFolderWorkspaceIdentifier(obj: any): obj is ISingleFolderWorkspaceIdentifier {
|
||||
@@ -109,13 +125,13 @@ export function isSingleFolderWorkspaceIdentifier(obj: any): obj is ISingleFolde
|
||||
export function isWorkspaceIdentifier(obj: any): obj is IWorkspaceIdentifier {
|
||||
const workspaceIdentifier = obj as IWorkspaceIdentifier;
|
||||
|
||||
return workspaceIdentifier && typeof workspaceIdentifier.id === 'string' && typeof workspaceIdentifier.configPath === 'string';
|
||||
return workspaceIdentifier && typeof workspaceIdentifier.id === 'string' && workspaceIdentifier.configPath instanceof URI;
|
||||
}
|
||||
|
||||
export function toWorkspaceIdentifier(workspace: IWorkspace): IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined {
|
||||
if (workspace.configuration) {
|
||||
return {
|
||||
configPath: workspace.configuration.fsPath,
|
||||
configPath: workspace.configuration,
|
||||
id: workspace.id
|
||||
};
|
||||
}
|
||||
@@ -136,3 +152,120 @@ export type IWorkspaceInitializationPayload = IMultiFolderWorkspaceInitializatio
|
||||
export function isSingleFolderWorkspaceInitializationPayload(obj: any): obj is ISingleFolderWorkspaceInitializationPayload {
|
||||
return isSingleFolderWorkspaceIdentifier((obj.folder as ISingleFolderWorkspaceIdentifier));
|
||||
}
|
||||
|
||||
const WORKSPACE_SUFFIX = '.' + WORKSPACE_EXTENSION;
|
||||
|
||||
export function hasWorkspaceFileExtension(path: string) {
|
||||
return extname(path) === WORKSPACE_SUFFIX;
|
||||
}
|
||||
|
||||
const SLASH = '/';
|
||||
|
||||
/**
|
||||
* Given a folder URI and the workspace config folder, computes the IStoredWorkspaceFolder using
|
||||
* a relative or absolute path or a uri.
|
||||
* Undefined is returned if the folderURI and the targetConfigFolderURI don't have the same schema or authority
|
||||
*
|
||||
* @param folderURI a workspace folder
|
||||
* @param folderName a workspace name
|
||||
* @param targetConfigFolderURI the folder where the workspace is living in
|
||||
* @param useSlashForPath if set, use forward slashes for file paths on windows
|
||||
*/
|
||||
export function getStoredWorkspaceFolder(folderURI: URI, folderName: string | undefined, targetConfigFolderURI: URI, useSlashForPath = !isWindows): IStoredWorkspaceFolder {
|
||||
|
||||
if (folderURI.scheme !== targetConfigFolderURI.scheme) {
|
||||
return { name: folderName, uri: folderURI.toString(true) };
|
||||
}
|
||||
|
||||
let folderPath: string | undefined;
|
||||
if (isEqualOrParent(folderURI, targetConfigFolderURI)) {
|
||||
// use relative path
|
||||
folderPath = relativePath(targetConfigFolderURI, folderURI) || '.'; // always uses forward slashes
|
||||
if (isWindows && folderURI.scheme === Schemas.file && !useSlashForPath) {
|
||||
// Windows gets special treatment:
|
||||
// - use backslahes unless slash is used by other existing folders
|
||||
folderPath = folderPath.replace(/\//g, '\\');
|
||||
}
|
||||
} else {
|
||||
// use absolute path
|
||||
if (folderURI.scheme === Schemas.file) {
|
||||
folderPath = folderURI.fsPath;
|
||||
if (isWindows) {
|
||||
// Windows gets special treatment:
|
||||
// - normalize all paths to get nice casing of drive letters
|
||||
// - use backslahes unless slash is used by other existing folders
|
||||
folderPath = normalizeDriveLetter(folderPath);
|
||||
if (useSlashForPath) {
|
||||
folderPath = toSlashes(folderPath);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!isEqualAuthority(folderURI.authority, targetConfigFolderURI.authority)) {
|
||||
return { name: folderName, uri: folderURI.toString(true) };
|
||||
}
|
||||
folderPath = folderURI.path;
|
||||
}
|
||||
}
|
||||
return { name: folderName, path: folderPath };
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrites the content of a workspace file to be saved at a new location.
|
||||
* Throws an exception if file is not a valid workspace file
|
||||
*/
|
||||
export function rewriteWorkspaceFileForNewLocation(rawWorkspaceContents: string, configPathURI: URI, targetConfigPathURI: URI) {
|
||||
let storedWorkspace = doParseStoredWorkspace(configPathURI, rawWorkspaceContents);
|
||||
|
||||
const sourceConfigFolder = dirname(configPathURI);
|
||||
const targetConfigFolder = dirname(targetConfigPathURI);
|
||||
|
||||
const rewrittenFolders: IStoredWorkspaceFolder[] = [];
|
||||
const slashForPath = useSlashForPath(storedWorkspace.folders);
|
||||
|
||||
// Rewrite absolute paths to relative paths if the target workspace folder
|
||||
// is a parent of the location of the workspace file itself. Otherwise keep
|
||||
// using absolute paths.
|
||||
for (const folder of storedWorkspace.folders) {
|
||||
let folderURI = isRawFileWorkspaceFolder(folder) ? resolvePath(sourceConfigFolder, folder.path) : URI.parse(folder.uri);
|
||||
rewrittenFolders.push(getStoredWorkspaceFolder(folderURI, folder.name, targetConfigFolder, slashForPath));
|
||||
}
|
||||
|
||||
// Preserve as much of the existing workspace as possible by using jsonEdit
|
||||
// and only changing the folders portion.
|
||||
let newRawWorkspaceContents = rawWorkspaceContents;
|
||||
const edits = jsonEdit.setProperty(rawWorkspaceContents, ['folders'], rewrittenFolders, { insertSpaces: false, tabSize: 4, eol: (isLinux || isMacintosh) ? '\n' : '\r\n' });
|
||||
edits.forEach(edit => {
|
||||
newRawWorkspaceContents = jsonEdit.applyEdit(rawWorkspaceContents, edit);
|
||||
});
|
||||
return newRawWorkspaceContents;
|
||||
}
|
||||
|
||||
function doParseStoredWorkspace(path: URI, contents: string): IStoredWorkspace {
|
||||
|
||||
// Parse workspace file
|
||||
let storedWorkspace: IStoredWorkspace = json.parse(contents); // use fault tolerant parser
|
||||
|
||||
// Filter out folders which do not have a path or uri set
|
||||
if (Array.isArray(storedWorkspace.folders)) {
|
||||
storedWorkspace.folders = storedWorkspace.folders.filter(folder => isStoredWorkspaceFolder(folder));
|
||||
}
|
||||
|
||||
// Validate
|
||||
if (!Array.isArray(storedWorkspace.folders)) {
|
||||
throw new Error(`${path} looks like an invalid workspace file.`);
|
||||
}
|
||||
|
||||
return storedWorkspace;
|
||||
}
|
||||
|
||||
export function useSlashForPath(storedFolders: IStoredWorkspaceFolder[]): boolean {
|
||||
if (isWindows) {
|
||||
for (const folder of storedFolders) {
|
||||
if (isRawFileWorkspaceFolder(folder) && folder.path.indexOf(SLASH) >= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IWorkspacesService, IWorkspaceIdentifier, IWorkspaceFolderCreationData, reviveWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
|
||||
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export class WorkspacesService implements IWorkspacesService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
|
||||
private channel: IChannel;
|
||||
|
||||
constructor(@IMainProcessService mainProcessService: IMainProcessService) {
|
||||
this.channel = mainProcessService.getChannel('workspaces');
|
||||
}
|
||||
|
||||
createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise<IWorkspaceIdentifier> {
|
||||
return this.channel.call('createUntitledWorkspace', [folders, remoteAuthority]).then(reviveWorkspaceIdentifier);
|
||||
}
|
||||
|
||||
deleteUntitledWorkspace(workspaceIdentifier: IWorkspaceIdentifier): Promise<void> {
|
||||
return this.channel.call('deleteUntitledWorkspace', workspaceIdentifier);
|
||||
}
|
||||
|
||||
getWorkspaceIdentifier(configPath: URI): Promise<IWorkspaceIdentifier> {
|
||||
return this.channel.call('getWorkspaceIdentifier', configPath);
|
||||
}
|
||||
}
|
||||
@@ -3,36 +3,33 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWorkspacesMainService, IWorkspaceIdentifier, WORKSPACE_EXTENSION, UNTITLED_WORKSPACE_NAME, IResolvedWorkspace, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { isParent } from 'vs/platform/files/common/files';
|
||||
import { IWorkspacesMainService, IWorkspaceIdentifier, hasWorkspaceFileExtension, UNTITLED_WORKSPACE_NAME, IResolvedWorkspace, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, IUntitledWorkspaceInfo, getStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { join, dirname, extname } from 'path';
|
||||
import { mkdirp, writeFile, readFile } from 'vs/base/node/pfs';
|
||||
import { join, dirname } from 'vs/base/common/path';
|
||||
import { mkdirp, writeFile } from 'vs/base/node/pfs';
|
||||
import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs';
|
||||
import { isLinux } from 'vs/base/common/platform';
|
||||
import { delSync, readdirSync, writeFileAndFlushSync } from 'vs/base/node/extfs';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { isEqual } from 'vs/base/common/paths';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { createHash } from 'crypto';
|
||||
import * as json from 'vs/base/common/json';
|
||||
import { massageFolderPathForWorkspace, rewriteWorkspaceFileForNewLocation } from 'vs/platform/workspaces/node/workspaces';
|
||||
import { toWorkspaceFolders } from 'vs/platform/workspace/common/workspace';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { fsPath, dirname as resourcesDirname } from 'vs/base/common/resources';
|
||||
import { originalFSPath, dirname as resourcesDirname, isEqualOrParent, joinPath } from 'vs/base/common/resources';
|
||||
|
||||
export interface IStoredWorkspace {
|
||||
folders: IStoredWorkspaceFolder[];
|
||||
remoteAuthority?: string;
|
||||
}
|
||||
|
||||
export class WorkspacesMainService extends Disposable implements IWorkspacesMainService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private workspacesHome: string;
|
||||
private readonly untitledWorkspacesHome: URI; // local URI that contains all untitled workspaces
|
||||
|
||||
private readonly _onUntitledWorkspaceDeleted = this._register(new Emitter<IWorkspaceIdentifier>());
|
||||
get onUntitledWorkspaceDeleted(): Event<IWorkspaceIdentifier> { return this._onUntitledWorkspaceDeleted.event; }
|
||||
@@ -43,36 +40,40 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain
|
||||
) {
|
||||
super();
|
||||
|
||||
this.workspacesHome = environmentService.workspacesHome;
|
||||
this.untitledWorkspacesHome = environmentService.untitledWorkspacesHome;
|
||||
}
|
||||
|
||||
resolveWorkspaceSync(path: string): IResolvedWorkspace | null {
|
||||
if (!this.isWorkspacePath(path)) {
|
||||
resolveLocalWorkspaceSync(uri: URI): IResolvedWorkspace | null {
|
||||
if (!this.isWorkspacePath(uri)) {
|
||||
return null; // does not look like a valid workspace config file
|
||||
}
|
||||
if (uri.scheme !== Schemas.file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let contents: string;
|
||||
try {
|
||||
contents = readFileSync(path, 'utf8');
|
||||
contents = readFileSync(uri.fsPath, 'utf8');
|
||||
} catch (error) {
|
||||
return null; // invalid workspace
|
||||
}
|
||||
|
||||
return this.doResolveWorkspace(URI.file(path), contents);
|
||||
return this.doResolveWorkspace(uri, contents);
|
||||
}
|
||||
|
||||
private isWorkspacePath(path: string): boolean {
|
||||
return this.isInsideWorkspacesHome(path) || extname(path) === `.${WORKSPACE_EXTENSION}`;
|
||||
private isWorkspacePath(uri: URI): boolean {
|
||||
return this.isInsideWorkspacesHome(uri) || hasWorkspaceFileExtension(uri.path);
|
||||
}
|
||||
|
||||
private doResolveWorkspace(path: URI, contents: string): IResolvedWorkspace | null {
|
||||
try {
|
||||
const workspace = this.doParseStoredWorkspace(path, contents);
|
||||
const workspaceIdentifier = this.getWorkspaceIdentifier(path);
|
||||
const workspaceIdentifier = getWorkspaceIdentifier(path);
|
||||
return {
|
||||
id: workspaceIdentifier.id,
|
||||
configPath: workspaceIdentifier.configPath,
|
||||
folders: toWorkspaceFolders(workspace.folders, resourcesDirname(path)!)
|
||||
folders: toWorkspaceFolders(workspace.folders, resourcesDirname(path)),
|
||||
remoteAuthority: workspace.remoteAuthority
|
||||
};
|
||||
} catch (error) {
|
||||
this.logService.warn(error.toString());
|
||||
@@ -99,135 +100,87 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain
|
||||
return storedWorkspace;
|
||||
}
|
||||
|
||||
private isInsideWorkspacesHome(path: string): boolean {
|
||||
return isParent(path, this.environmentService.workspacesHome, !isLinux /* ignore case */);
|
||||
private isInsideWorkspacesHome(path: URI): boolean {
|
||||
return isEqualOrParent(path, this.environmentService.untitledWorkspacesHome);
|
||||
}
|
||||
|
||||
createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[]): Promise<IWorkspaceIdentifier> {
|
||||
const { workspace, configParent, storedWorkspace } = this.newUntitledWorkspace(folders);
|
||||
createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise<IWorkspaceIdentifier> {
|
||||
const { workspace, storedWorkspace } = this.newUntitledWorkspace(folders, remoteAuthority);
|
||||
const configPath = workspace.configPath.fsPath;
|
||||
|
||||
return mkdirp(configParent).then(() => {
|
||||
return writeFile(workspace.configPath, JSON.stringify(storedWorkspace, null, '\t')).then(() => workspace);
|
||||
return mkdirp(dirname(configPath)).then(() => {
|
||||
return writeFile(configPath, JSON.stringify(storedWorkspace, null, '\t')).then(() => workspace);
|
||||
});
|
||||
}
|
||||
|
||||
createUntitledWorkspaceSync(folders?: IWorkspaceFolderCreationData[]): IWorkspaceIdentifier {
|
||||
const { workspace, configParent, storedWorkspace } = this.newUntitledWorkspace(folders);
|
||||
createUntitledWorkspaceSync(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): IWorkspaceIdentifier {
|
||||
const { workspace, storedWorkspace } = this.newUntitledWorkspace(folders, remoteAuthority);
|
||||
const configPath = workspace.configPath.fsPath;
|
||||
|
||||
if (!existsSync(this.workspacesHome)) {
|
||||
mkdirSync(this.workspacesHome);
|
||||
const configPathDir = dirname(configPath);
|
||||
if (!existsSync(configPathDir)) {
|
||||
const configPathDirDir = dirname(configPathDir);
|
||||
if (!existsSync(configPathDirDir)) {
|
||||
mkdirSync(configPathDirDir);
|
||||
}
|
||||
mkdirSync(configPathDir);
|
||||
}
|
||||
|
||||
mkdirSync(configParent);
|
||||
|
||||
writeFileAndFlushSync(workspace.configPath, JSON.stringify(storedWorkspace, null, '\t'));
|
||||
writeFileAndFlushSync(configPath, JSON.stringify(storedWorkspace, null, '\t'));
|
||||
|
||||
return workspace;
|
||||
}
|
||||
|
||||
private newUntitledWorkspace(folders: IWorkspaceFolderCreationData[] = []): { workspace: IWorkspaceIdentifier, configParent: string, storedWorkspace: IStoredWorkspace } {
|
||||
private newUntitledWorkspace(folders: IWorkspaceFolderCreationData[] = [], remoteAuthority?: string): { workspace: IWorkspaceIdentifier, storedWorkspace: IStoredWorkspace } {
|
||||
const randomId = (Date.now() + Math.round(Math.random() * 1000)).toString();
|
||||
const untitledWorkspaceConfigFolder = join(this.workspacesHome, randomId);
|
||||
const untitledWorkspaceConfigPath = join(untitledWorkspaceConfigFolder, UNTITLED_WORKSPACE_NAME);
|
||||
const untitledWorkspaceConfigFolder = joinPath(this.untitledWorkspacesHome, randomId);
|
||||
const untitledWorkspaceConfigPath = joinPath(untitledWorkspaceConfigFolder, UNTITLED_WORKSPACE_NAME);
|
||||
|
||||
const storedWorkspace: IStoredWorkspace = {
|
||||
folders: folders.map(folder => {
|
||||
const folderResource = folder.uri;
|
||||
let storedWorkspace: IStoredWorkspaceFolder;
|
||||
const storedWorkspaceFolder: IStoredWorkspaceFolder[] = [];
|
||||
|
||||
// File URI
|
||||
if (folderResource.scheme === Schemas.file) {
|
||||
storedWorkspace = { path: massageFolderPathForWorkspace(fsPath(folderResource), URI.file(untitledWorkspaceConfigFolder), []) };
|
||||
}
|
||||
|
||||
// Any URI
|
||||
else {
|
||||
storedWorkspace = { uri: folderResource.toString(true) };
|
||||
}
|
||||
|
||||
if (folder.name) {
|
||||
storedWorkspace.name = folder.name;
|
||||
}
|
||||
|
||||
return storedWorkspace;
|
||||
})
|
||||
};
|
||||
for (const folder of folders) {
|
||||
storedWorkspaceFolder.push(getStoredWorkspaceFolder(folder.uri, folder.name, untitledWorkspaceConfigFolder));
|
||||
}
|
||||
|
||||
return {
|
||||
workspace: {
|
||||
id: this.getWorkspaceId(untitledWorkspaceConfigPath),
|
||||
configPath: untitledWorkspaceConfigPath
|
||||
},
|
||||
configParent: untitledWorkspaceConfigFolder,
|
||||
storedWorkspace
|
||||
workspace: getWorkspaceIdentifier(untitledWorkspaceConfigPath),
|
||||
storedWorkspace: { folders: storedWorkspaceFolder, remoteAuthority }
|
||||
};
|
||||
}
|
||||
|
||||
getWorkspaceId(workspaceConfigPath: string): string {
|
||||
if (!isLinux) {
|
||||
workspaceConfigPath = workspaceConfigPath.toLowerCase(); // sanitize for platform file system
|
||||
}
|
||||
|
||||
return createHash('md5').update(workspaceConfigPath).digest('hex');
|
||||
}
|
||||
|
||||
getWorkspaceIdentifier(workspacePath: URI): IWorkspaceIdentifier {
|
||||
if (workspacePath.scheme === Schemas.file) {
|
||||
const configPath = fsPath(workspacePath);
|
||||
return {
|
||||
configPath,
|
||||
id: this.getWorkspaceId(configPath)
|
||||
};
|
||||
}
|
||||
throw new Error('Not yet supported');
|
||||
/*return {
|
||||
configPath: workspacePath
|
||||
id: this.getWorkspaceId(workspacePath.toString());
|
||||
};*/
|
||||
getWorkspaceIdentifier(configPath: URI): Promise<IWorkspaceIdentifier> {
|
||||
return Promise.resolve(getWorkspaceIdentifier(configPath));
|
||||
}
|
||||
|
||||
isUntitledWorkspace(workspace: IWorkspaceIdentifier): boolean {
|
||||
return this.isInsideWorkspacesHome(workspace.configPath);
|
||||
}
|
||||
|
||||
saveWorkspaceAs(workspace: IWorkspaceIdentifier, targetConfigPath: string): Promise<IWorkspaceIdentifier> {
|
||||
|
||||
// Return early if target is same as source
|
||||
if (isEqual(workspace.configPath, targetConfigPath, !isLinux)) {
|
||||
return Promise.resolve(workspace);
|
||||
}
|
||||
|
||||
// Read the contents of the workspace file and resolve it
|
||||
return readFile(workspace.configPath).then(raw => {
|
||||
const targetConfigPathURI = URI.file(targetConfigPath);
|
||||
const newRawWorkspaceContents = rewriteWorkspaceFileForNewLocation(raw.toString(), URI.file(workspace.configPath), targetConfigPathURI);
|
||||
|
||||
return writeFile(targetConfigPath, newRawWorkspaceContents).then(() => {
|
||||
return this.getWorkspaceIdentifier(targetConfigPathURI);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
deleteUntitledWorkspaceSync(workspace: IWorkspaceIdentifier): void {
|
||||
if (!this.isUntitledWorkspace(workspace)) {
|
||||
return; // only supported for untitled workspaces
|
||||
}
|
||||
|
||||
// Delete from disk
|
||||
this.doDeleteUntitledWorkspaceSync(workspace.configPath);
|
||||
this.doDeleteUntitledWorkspaceSync(workspace);
|
||||
|
||||
// Event
|
||||
this._onUntitledWorkspaceDeleted.fire(workspace);
|
||||
}
|
||||
|
||||
private doDeleteUntitledWorkspaceSync(configPath: string): void {
|
||||
try {
|
||||
deleteUntitledWorkspace(workspace: IWorkspaceIdentifier): Promise<void> {
|
||||
this.deleteUntitledWorkspaceSync(workspace);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
private doDeleteUntitledWorkspaceSync(workspace: IWorkspaceIdentifier): void {
|
||||
const configPath = originalFSPath(workspace.configPath);
|
||||
try {
|
||||
// Delete Workspace
|
||||
delSync(dirname(configPath));
|
||||
|
||||
// Mark Workspace Storage to be deleted
|
||||
const workspaceStoragePath = join(this.environmentService.workspaceStorageHome, this.getWorkspaceId(configPath));
|
||||
const workspaceStoragePath = join(this.environmentService.workspaceStorageHome, workspace.id);
|
||||
if (existsSync(workspaceStoragePath)) {
|
||||
writeFileSync(join(workspaceStoragePath, 'obsolete'), '');
|
||||
}
|
||||
@@ -236,27 +189,40 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain
|
||||
}
|
||||
}
|
||||
|
||||
getUntitledWorkspacesSync(): IWorkspaceIdentifier[] {
|
||||
let untitledWorkspacePaths: string[] = [];
|
||||
getUntitledWorkspacesSync(): IUntitledWorkspaceInfo[] {
|
||||
let untitledWorkspaces: IUntitledWorkspaceInfo[] = [];
|
||||
try {
|
||||
untitledWorkspacePaths = readdirSync(this.workspacesHome).map(folder => join(this.workspacesHome, folder, UNTITLED_WORKSPACE_NAME));
|
||||
const untitledWorkspacePaths = readdirSync(this.untitledWorkspacesHome.fsPath).map(folder => joinPath(this.untitledWorkspacesHome, folder, UNTITLED_WORKSPACE_NAME));
|
||||
for (const untitledWorkspacePath of untitledWorkspacePaths) {
|
||||
const workspace = getWorkspaceIdentifier(untitledWorkspacePath);
|
||||
const resolvedWorkspace = this.resolveLocalWorkspaceSync(untitledWorkspacePath);
|
||||
if (!resolvedWorkspace) {
|
||||
this.doDeleteUntitledWorkspaceSync(workspace);
|
||||
} else {
|
||||
untitledWorkspaces.push({ workspace, remoteAuthority: resolvedWorkspace.remoteAuthority });
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (error && error.code !== 'ENOENT') {
|
||||
this.logService.warn(`Unable to read folders in ${this.workspacesHome} (${error}).`);
|
||||
this.logService.warn(`Unable to read folders in ${this.untitledWorkspacesHome} (${error}).`);
|
||||
}
|
||||
}
|
||||
|
||||
const untitledWorkspaces: IWorkspaceIdentifier[] = coalesce(untitledWorkspacePaths.map(untitledWorkspacePath => {
|
||||
const workspace = this.resolveWorkspaceSync(untitledWorkspacePath);
|
||||
if (!workspace) {
|
||||
this.doDeleteUntitledWorkspaceSync(untitledWorkspacePath);
|
||||
|
||||
return null; // invalid workspace
|
||||
}
|
||||
|
||||
return { id: workspace.id, configPath: untitledWorkspacePath };
|
||||
}));
|
||||
|
||||
return untitledWorkspaces;
|
||||
}
|
||||
}
|
||||
|
||||
function getWorkspaceId(configPath: URI): string {
|
||||
let workspaceConfigPath = configPath.scheme === Schemas.file ? originalFSPath(configPath) : configPath.toString();
|
||||
if (!isLinux) {
|
||||
workspaceConfigPath = workspaceConfigPath.toLowerCase(); // sanitize for platform file system
|
||||
}
|
||||
|
||||
return createHash('md5').update(workspaceConfigPath).digest('hex');
|
||||
}
|
||||
|
||||
export function getWorkspaceIdentifier(configPath: URI): IWorkspaceIdentifier {
|
||||
return {
|
||||
configPath,
|
||||
id: getWorkspaceId(configPath)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IStoredWorkspaceFolder, isRawFileWorkspaceFolder, IStoredWorkspace, isStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform';
|
||||
import { isAbsolute, relative, posix, resolve } from 'path';
|
||||
import { normalize, isEqualOrParent } from 'vs/base/common/paths';
|
||||
import { normalizeDriveLetter } from 'vs/base/common/labels';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { fsPath, dirname } from 'vs/base/common/resources';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import * as jsonEdit from 'vs/base/common/jsonEdit';
|
||||
import * as json from 'vs/base/common/json';
|
||||
|
||||
const SLASH = '/';
|
||||
|
||||
/**
|
||||
* Given the absolute path to a folder, massage it in a way that it fits
|
||||
* into an existing set of workspace folders of a workspace.
|
||||
*
|
||||
* @param absoluteFolderPath the absolute path of a workspace folder
|
||||
* @param targetConfigFolder the folder where the workspace is living in
|
||||
* @param existingFolders a set of existing folders of the workspace
|
||||
*/
|
||||
export function massageFolderPathForWorkspace(absoluteFolderPath: string, targetConfigFolderURI: URI, existingFolders: IStoredWorkspaceFolder[]): string {
|
||||
|
||||
if (targetConfigFolderURI.scheme === Schemas.file) {
|
||||
const targetFolderPath = fsPath(targetConfigFolderURI);
|
||||
// Convert path to relative path if the target config folder
|
||||
// is a parent of the path.
|
||||
if (isEqualOrParent(absoluteFolderPath, targetFolderPath, !isLinux)) {
|
||||
absoluteFolderPath = relative(targetFolderPath, absoluteFolderPath) || '.';
|
||||
}
|
||||
|
||||
// Windows gets special treatment:
|
||||
// - normalize all paths to get nice casing of drive letters
|
||||
// - convert to slashes if we want to use slashes for paths
|
||||
if (isWindows) {
|
||||
if (isAbsolute(absoluteFolderPath)) {
|
||||
if (shouldUseSlashForPath(existingFolders)) {
|
||||
absoluteFolderPath = normalize(absoluteFolderPath, false /* do not use OS path separator */);
|
||||
}
|
||||
|
||||
absoluteFolderPath = normalizeDriveLetter(absoluteFolderPath);
|
||||
} else if (shouldUseSlashForPath(existingFolders)) {
|
||||
absoluteFolderPath = absoluteFolderPath.replace(/[\\]/g, SLASH);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isEqualOrParent(absoluteFolderPath, targetConfigFolderURI.path)) {
|
||||
absoluteFolderPath = posix.relative(absoluteFolderPath, targetConfigFolderURI.path) || '.';
|
||||
}
|
||||
}
|
||||
|
||||
return absoluteFolderPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrites the content of a workspace file to be saved at a new location.
|
||||
* Throws an exception if file is not a valid workspace file
|
||||
*/
|
||||
export function rewriteWorkspaceFileForNewLocation(rawWorkspaceContents: string, configPathURI: URI, targetConfigPathURI: URI) {
|
||||
let storedWorkspace = doParseStoredWorkspace(configPathURI, rawWorkspaceContents);
|
||||
|
||||
const sourceConfigFolder = dirname(configPathURI)!;
|
||||
const targetConfigFolder = dirname(targetConfigPathURI)!;
|
||||
|
||||
// Rewrite absolute paths to relative paths if the target workspace folder
|
||||
// is a parent of the location of the workspace file itself. Otherwise keep
|
||||
// using absolute paths.
|
||||
for (const folder of storedWorkspace.folders) {
|
||||
if (isRawFileWorkspaceFolder(folder)) {
|
||||
if (sourceConfigFolder.scheme === Schemas.file) {
|
||||
if (!isAbsolute(folder.path)) {
|
||||
folder.path = resolve(fsPath(sourceConfigFolder), folder.path); // relative paths get resolved against the workspace location
|
||||
}
|
||||
folder.path = massageFolderPathForWorkspace(folder.path, targetConfigFolder, storedWorkspace.folders);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve as much of the existing workspace as possible by using jsonEdit
|
||||
// and only changing the folders portion.
|
||||
let newRawWorkspaceContents = rawWorkspaceContents;
|
||||
const edits = jsonEdit.setProperty(rawWorkspaceContents, ['folders'], storedWorkspace.folders, { insertSpaces: false, tabSize: 4, eol: (isLinux || isMacintosh) ? '\n' : '\r\n' });
|
||||
edits.forEach(edit => {
|
||||
newRawWorkspaceContents = jsonEdit.applyEdit(rawWorkspaceContents, edit);
|
||||
});
|
||||
return newRawWorkspaceContents;
|
||||
}
|
||||
|
||||
function doParseStoredWorkspace(path: URI, contents: string): IStoredWorkspace {
|
||||
|
||||
// Parse workspace file
|
||||
let storedWorkspace: IStoredWorkspace = json.parse(contents); // use fault tolerant parser
|
||||
|
||||
// Filter out folders which do not have a path or uri set
|
||||
if (Array.isArray(storedWorkspace.folders)) {
|
||||
storedWorkspace.folders = storedWorkspace.folders.filter(folder => isStoredWorkspaceFolder(folder));
|
||||
}
|
||||
|
||||
// Validate
|
||||
if (!Array.isArray(storedWorkspace.folders)) {
|
||||
throw new Error(`${path} looks like an invalid workspace file.`);
|
||||
}
|
||||
|
||||
return storedWorkspace;
|
||||
}
|
||||
|
||||
function shouldUseSlashForPath(storedFolders: IStoredWorkspaceFolder[]): boolean {
|
||||
|
||||
// Determine which path separator to use:
|
||||
// - macOS/Linux: slash
|
||||
// - Windows: use slash if already used in that file
|
||||
let useSlashesForPath = !isWindows;
|
||||
if (isWindows) {
|
||||
storedFolders.forEach(folder => {
|
||||
if (isRawFileWorkspaceFolder(folder) && !useSlashesForPath && folder.path.indexOf(SLASH) >= 0) {
|
||||
useSlashesForPath = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return useSlashesForPath;
|
||||
}
|
||||
@@ -3,8 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/node/ipc';
|
||||
import { IWorkspacesService, IWorkspaceIdentifier, IWorkspaceFolderCreationData, IWorkspacesMainService } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IServerChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, IWorkspacesMainService } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
@@ -19,7 +19,8 @@ export class WorkspacesChannel implements IServerChannel {
|
||||
call(_, command: string, arg?: any): Promise<any> {
|
||||
switch (command) {
|
||||
case 'createUntitledWorkspace': {
|
||||
const rawFolders: IWorkspaceFolderCreationData[] = arg;
|
||||
const rawFolders: IWorkspaceFolderCreationData[] = arg[0];
|
||||
const remoteAuthority: string = arg[1];
|
||||
let folders: IWorkspaceFolderCreationData[] | undefined = undefined;
|
||||
if (Array.isArray(rawFolders)) {
|
||||
folders = rawFolders.map(rawFolder => {
|
||||
@@ -30,21 +31,17 @@ export class WorkspacesChannel implements IServerChannel {
|
||||
});
|
||||
}
|
||||
|
||||
return this.service.createUntitledWorkspace(folders);
|
||||
return this.service.createUntitledWorkspace(folders, remoteAuthority);
|
||||
}
|
||||
case 'deleteUntitledWorkspace': {
|
||||
const w: IWorkspaceIdentifier = arg;
|
||||
return this.service.deleteUntitledWorkspace({ id: w.id, configPath: URI.revive(w.configPath) });
|
||||
}
|
||||
case 'getWorkspaceIdentifier': {
|
||||
return this.service.getWorkspaceIdentifier(URI.revive(arg));
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Call not found: ${command}`);
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkspacesChannelClient implements IWorkspacesService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
constructor(private channel: IChannel) { }
|
||||
|
||||
createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[]): Promise<IWorkspaceIdentifier> {
|
||||
return this.channel.call('createUntitledWorkspace', folders);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,26 +6,25 @@
|
||||
import * as assert from 'assert';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as extfs from 'vs/base/node/extfs';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import { parseArgs } from 'vs/platform/environment/node/argv';
|
||||
import { WorkspacesMainService, IStoredWorkspace } from 'vs/platform/workspaces/electron-main/workspacesMainService';
|
||||
import { WORKSPACE_EXTENSION, IWorkspaceIdentifier, IRawFileWorkspaceFolder, IWorkspaceFolderCreationData, IRawUriWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { WORKSPACE_EXTENSION, IWorkspaceIdentifier, IRawFileWorkspaceFolder, IWorkspaceFolderCreationData, IRawUriWorkspaceFolder, rewriteWorkspaceFileForNewLocation } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { getRandomTestPath } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { getRandomTestPath } from 'vs/base/test/node/testUtils';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { normalizeDriveLetter } from 'vs/base/common/labels';
|
||||
|
||||
suite('WorkspacesMainService', () => {
|
||||
const parentDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'workspacesservice');
|
||||
const workspacesHome = path.join(parentDir, 'Workspaces');
|
||||
const untitledWorkspacesHomePath = path.join(parentDir, 'Workspaces');
|
||||
|
||||
class TestEnvironmentService extends EnvironmentService {
|
||||
get workspacesHome(): string {
|
||||
return workspacesHome;
|
||||
get untitledWorkspacesHome(): URI {
|
||||
return URI.file(untitledWorkspacesHomePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +55,13 @@ suite('WorkspacesMainService', () => {
|
||||
service = new TestWorkspacesMainService(environmentService, logService);
|
||||
|
||||
// Delete any existing backups completely and then re-create it.
|
||||
return pfs.del(workspacesHome, os.tmpdir()).then(() => {
|
||||
return pfs.mkdirp(workspacesHome);
|
||||
return pfs.del(untitledWorkspacesHomePath, os.tmpdir()).then(() => {
|
||||
return pfs.mkdirp(untitledWorkspacesHomePath);
|
||||
});
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
return pfs.del(workspacesHome, os.tmpdir());
|
||||
return pfs.del(untitledWorkspacesHomePath, os.tmpdir());
|
||||
});
|
||||
|
||||
function assertPathEquals(p1: string, p2): void {
|
||||
@@ -74,13 +73,17 @@ suite('WorkspacesMainService', () => {
|
||||
assert.equal(p1, p2);
|
||||
}
|
||||
|
||||
function assertEqualURI(u1: URI, u2: URI): void {
|
||||
assert.equal(u1.toString(), u2.toString());
|
||||
}
|
||||
|
||||
test('createWorkspace (folders)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
assert.ok(workspace);
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(fs.existsSync(workspace.configPath.fsPath));
|
||||
assert.ok(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 2); //
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd());
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, os.tmpdir());
|
||||
@@ -93,10 +96,10 @@ suite('WorkspacesMainService', () => {
|
||||
test('createWorkspace (folders with name)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()], ['currentworkingdirectory', 'tempdir']).then(workspace => {
|
||||
assert.ok(workspace);
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(fs.existsSync(workspace.configPath.fsPath));
|
||||
assert.ok(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 2); //
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd());
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, os.tmpdir());
|
||||
@@ -107,28 +110,33 @@ suite('WorkspacesMainService', () => {
|
||||
});
|
||||
|
||||
test('createUntitledWorkspace (folders as other resource URIs)', () => {
|
||||
return service.createUntitledWorkspace([{ uri: URI.from({ scheme: 'myScheme', path: process.cwd() }) }, { uri: URI.from({ scheme: 'myScheme', path: os.tmpdir() }) }]).then(workspace => {
|
||||
const folder1URI = URI.parse('myscheme://server/work/p/f1');
|
||||
const folder2URI = URI.parse('myscheme://server/work/o/f3');
|
||||
|
||||
return service.createUntitledWorkspace([{ uri: folder1URI }, { uri: folder2URI }], 'server').then(workspace => {
|
||||
assert.ok(workspace);
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(fs.existsSync(workspace.configPath.fsPath));
|
||||
assert.ok(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 2);
|
||||
assert.equal((<IRawUriWorkspaceFolder>ws.folders[0]).uri, URI.from({ scheme: 'myScheme', path: process.cwd() }).toString(true));
|
||||
assert.equal((<IRawUriWorkspaceFolder>ws.folders[1]).uri, URI.from({ scheme: 'myScheme', path: os.tmpdir() }).toString(true));
|
||||
assert.equal((<IRawUriWorkspaceFolder>ws.folders[0]).uri, folder1URI.toString(true));
|
||||
assert.equal((<IRawUriWorkspaceFolder>ws.folders[1]).uri, folder2URI.toString(true));
|
||||
|
||||
assert.ok(!(<IRawFileWorkspaceFolder>ws.folders[0]).name);
|
||||
assert.ok(!(<IRawFileWorkspaceFolder>ws.folders[1]).name);
|
||||
|
||||
assert.equal(ws.remoteAuthority, 'server');
|
||||
});
|
||||
});
|
||||
|
||||
test('createWorkspaceSync (folders)', () => {
|
||||
const workspace = createWorkspaceSync([process.cwd(), os.tmpdir()]);
|
||||
assert.ok(workspace);
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(fs.existsSync(workspace.configPath.fsPath));
|
||||
assert.ok(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 2);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd());
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, os.tmpdir());
|
||||
@@ -140,10 +148,10 @@ suite('WorkspacesMainService', () => {
|
||||
test('createWorkspaceSync (folders with names)', () => {
|
||||
const workspace = createWorkspaceSync([process.cwd(), os.tmpdir()], ['currentworkingdirectory', 'tempdir']);
|
||||
assert.ok(workspace);
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(fs.existsSync(workspace.configPath.fsPath));
|
||||
assert.ok(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 2);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd());
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, os.tmpdir());
|
||||
@@ -153,15 +161,18 @@ suite('WorkspacesMainService', () => {
|
||||
});
|
||||
|
||||
test('createUntitledWorkspaceSync (folders as other resource URIs)', () => {
|
||||
const workspace = service.createUntitledWorkspaceSync([{ uri: URI.from({ scheme: 'myScheme', path: process.cwd() }) }, { uri: URI.from({ scheme: 'myScheme', path: os.tmpdir() }) }]);
|
||||
const folder1URI = URI.parse('myscheme://server/work/p/f1');
|
||||
const folder2URI = URI.parse('myscheme://server/work/o/f3');
|
||||
|
||||
const workspace = service.createUntitledWorkspaceSync([{ uri: folder1URI }, { uri: folder2URI }]);
|
||||
assert.ok(workspace);
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(fs.existsSync(workspace.configPath.fsPath));
|
||||
assert.ok(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 2);
|
||||
assert.equal((<IRawUriWorkspaceFolder>ws.folders[0]).uri, URI.from({ scheme: 'myScheme', path: process.cwd() }).toString(true));
|
||||
assert.equal((<IRawUriWorkspaceFolder>ws.folders[1]).uri, URI.from({ scheme: 'myScheme', path: os.tmpdir() }).toString(true));
|
||||
assert.equal((<IRawUriWorkspaceFolder>ws.folders[0]).uri, folder1URI.toString(true));
|
||||
assert.equal((<IRawUriWorkspaceFolder>ws.folders[1]).uri, folder2URI.toString(true));
|
||||
|
||||
assert.ok(!(<IRawFileWorkspaceFolder>ws.folders[0]).name);
|
||||
assert.ok(!(<IRawFileWorkspaceFolder>ws.folders[1]).name);
|
||||
@@ -169,195 +180,202 @@ suite('WorkspacesMainService', () => {
|
||||
|
||||
test('resolveWorkspaceSync', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
assert.ok(service.resolveWorkspaceSync(workspace.configPath));
|
||||
assert.ok(service.resolveLocalWorkspaceSync(workspace.configPath));
|
||||
|
||||
// make it a valid workspace path
|
||||
const newPath = path.join(path.dirname(workspace.configPath), `workspace.${WORKSPACE_EXTENSION}`);
|
||||
fs.renameSync(workspace.configPath, newPath);
|
||||
workspace.configPath = newPath;
|
||||
const newPath = path.join(path.dirname(workspace.configPath.fsPath), `workspace.${WORKSPACE_EXTENSION}`);
|
||||
fs.renameSync(workspace.configPath.fsPath, newPath);
|
||||
workspace.configPath = URI.file(newPath);
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
const resolved = service.resolveLocalWorkspaceSync(workspace.configPath);
|
||||
assert.equal(2, resolved!.folders.length);
|
||||
assert.equal(resolved!.configPath, workspace.configPath);
|
||||
assertEqualURI(resolved!.configPath, workspace.configPath);
|
||||
assert.ok(resolved!.id);
|
||||
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ something: 'something' })); // invalid workspace
|
||||
const resolvedInvalid = service.resolveWorkspaceSync(workspace.configPath);
|
||||
fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ something: 'something' })); // invalid workspace
|
||||
const resolvedInvalid = service.resolveLocalWorkspaceSync(workspace.configPath);
|
||||
assert.ok(!resolvedInvalid);
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support relative paths)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib' }] }));
|
||||
fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib' }] }));
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(resolved!.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
const resolved = service.resolveLocalWorkspaceSync(workspace.configPath);
|
||||
assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'lib')));
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support relative paths #2)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib/../other' }] }));
|
||||
fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib/../other' }] }));
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(resolved!.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'other')).fsPath);
|
||||
const resolved = service.resolveLocalWorkspaceSync(workspace.configPath);
|
||||
assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'other')));
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support relative paths #3)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: 'ticino-playground/lib' }] }));
|
||||
fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: 'ticino-playground/lib' }] }));
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(resolved!.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
const resolved = service.resolveLocalWorkspaceSync(workspace.configPath);
|
||||
assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'lib')));
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support invalid JSON via fault tolerant parsing)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
fs.writeFileSync(workspace.configPath, '{ "folders": [ { "path": "./ticino-playground/lib" } , ] }'); // trailing comma
|
||||
fs.writeFileSync(workspace.configPath.fsPath, '{ "folders": [ { "path": "./ticino-playground/lib" } , ] }'); // trailing comma
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(resolved!.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
const resolved = service.resolveLocalWorkspaceSync(workspace.configPath);
|
||||
assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'lib')));
|
||||
});
|
||||
});
|
||||
|
||||
test('saveWorkspace (untitled)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => {
|
||||
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
|
||||
test('rewriteWorkspaceFileForNewLocation', () => {
|
||||
const folder1 = process.cwd(); // absolute path because outside of tmpDir
|
||||
const tmpDir = os.tmpdir();
|
||||
const tmpInsideDir = path.join(os.tmpdir(), 'inside');
|
||||
|
||||
return service.saveWorkspaceAs(workspace, workspaceConfigPath).then(savedWorkspace => {
|
||||
assert.ok(savedWorkspace.id);
|
||||
assert.notEqual(savedWorkspace.id, workspace.id);
|
||||
assert.equal(savedWorkspace.configPath, workspaceConfigPath);
|
||||
return createWorkspace([folder1, tmpInsideDir, path.join(tmpInsideDir, 'somefolder')]).then(workspace => {
|
||||
const origContent = fs.readFileSync(workspace.configPath.fsPath).toString();
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(savedWorkspace.configPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 3);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd()); // absolute
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, '.'); // relative
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[2]).path, path.relative(path.dirname(workspaceConfigPath), path.join(os.tmpdir(), 'somefolder'))); // relative
|
||||
let origConfigPath = workspace.configPath;
|
||||
let workspaceConfigPath = URI.file(path.join(tmpDir, 'inside', 'myworkspace1.code-workspace'));
|
||||
let newContent = rewriteWorkspaceFileForNewLocation(origContent, origConfigPath, workspaceConfigPath);
|
||||
|
||||
extfs.delSync(workspaceConfigPath);
|
||||
});
|
||||
let ws = JSON.parse(newContent) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 3);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, folder1); // absolute path because outside of tmpdir
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, '.');
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[2]).path, 'somefolder');
|
||||
|
||||
origConfigPath = workspaceConfigPath;
|
||||
workspaceConfigPath = URI.file(path.join(tmpDir, 'myworkspace2.code-workspace'));
|
||||
newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath);
|
||||
|
||||
ws = JSON.parse(newContent) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 3);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, folder1);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, 'inside');
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[2]).path, isWindows ? 'inside\\somefolder' : 'inside/somefolder');
|
||||
|
||||
origConfigPath = workspaceConfigPath;
|
||||
workspaceConfigPath = URI.file(path.join(tmpDir, 'other', 'myworkspace2.code-workspace'));
|
||||
newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath);
|
||||
|
||||
ws = JSON.parse(newContent) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 3);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, folder1);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, tmpInsideDir);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[2]).path, path.join(tmpInsideDir, 'somefolder'));
|
||||
|
||||
origConfigPath = workspaceConfigPath;
|
||||
workspaceConfigPath = URI.parse('foo://foo/bar/myworkspace2.code-workspace');
|
||||
newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath);
|
||||
|
||||
ws = JSON.parse(newContent) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 3);
|
||||
assert.equal((<IRawUriWorkspaceFolder>ws.folders[0]).uri, URI.file(folder1).toString(true));
|
||||
assert.equal((<IRawUriWorkspaceFolder>ws.folders[1]).uri, URI.file(tmpInsideDir).toString(true));
|
||||
assert.equal((<IRawUriWorkspaceFolder>ws.folders[2]).uri, URI.file(path.join(tmpInsideDir, 'somefolder')).toString(true));
|
||||
|
||||
service.deleteUntitledWorkspaceSync(workspace);
|
||||
});
|
||||
});
|
||||
|
||||
test('saveWorkspace (saved workspace)', () => {
|
||||
test('rewriteWorkspaceFileForNewLocation (preserves comments)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => {
|
||||
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
|
||||
const newWorkspaceConfigPath = path.join(os.tmpdir(), `mySavedWorkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
|
||||
const workspaceConfigPath = URI.file(path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`));
|
||||
|
||||
return service.saveWorkspaceAs(workspace, workspaceConfigPath).then(savedWorkspace => {
|
||||
return service.saveWorkspaceAs(savedWorkspace, newWorkspaceConfigPath).then(newSavedWorkspace => {
|
||||
assert.ok(newSavedWorkspace.id);
|
||||
assert.notEqual(newSavedWorkspace.id, workspace.id);
|
||||
assertPathEquals(newSavedWorkspace.configPath, newWorkspaceConfigPath);
|
||||
let origContent = fs.readFileSync(workspace.configPath.fsPath).toString();
|
||||
origContent = `// this is a comment\n${origContent}`;
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(newSavedWorkspace.configPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 3);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd()); // absolute path because outside of tmpdir
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, '.'); // relative path because inside of tmpdir
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[2]).path, path.relative(path.dirname(workspaceConfigPath), path.join(os.tmpdir(), 'somefolder'))); // relative
|
||||
let newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath);
|
||||
|
||||
extfs.delSync(workspaceConfigPath);
|
||||
extfs.delSync(newWorkspaceConfigPath);
|
||||
});
|
||||
});
|
||||
assert.equal(0, newContent.indexOf('// this is a comment'));
|
||||
|
||||
service.deleteUntitledWorkspaceSync(workspace);
|
||||
});
|
||||
});
|
||||
|
||||
test('saveWorkspace (saved workspace, preserves comments)', () => {
|
||||
test('rewriteWorkspaceFileForNewLocation (preserves forward slashes)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => {
|
||||
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
|
||||
const newWorkspaceConfigPath = path.join(os.tmpdir(), `mySavedWorkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
|
||||
const workspaceConfigPath = URI.file(path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`));
|
||||
let origContent = fs.readFileSync(workspace.configPath.fsPath).toString();
|
||||
origContent = origContent.replace(/[\\]/g, '/'); // convert backslash to slash
|
||||
|
||||
return service.saveWorkspaceAs(workspace, workspaceConfigPath).then(savedWorkspace => {
|
||||
const contents = fs.readFileSync(savedWorkspace.configPath).toString();
|
||||
fs.writeFileSync(savedWorkspace.configPath, `// this is a comment\n${contents}`);
|
||||
const newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath);
|
||||
|
||||
return service.saveWorkspaceAs(savedWorkspace, newWorkspaceConfigPath).then(newSavedWorkspace => {
|
||||
assert.ok(newSavedWorkspace.id);
|
||||
assert.notEqual(newSavedWorkspace.id, workspace.id);
|
||||
assertPathEquals(newSavedWorkspace.configPath, newWorkspaceConfigPath);
|
||||
const ws = JSON.parse(newContent) as IStoredWorkspace;
|
||||
assert.ok(ws.folders.every(f => (<IRawFileWorkspaceFolder>f).path.indexOf('\\') < 0));
|
||||
|
||||
const savedContents = fs.readFileSync(newSavedWorkspace.configPath).toString();
|
||||
assert.equal(0, savedContents.indexOf('// this is a comment'));
|
||||
|
||||
extfs.delSync(workspaceConfigPath);
|
||||
extfs.delSync(newWorkspaceConfigPath);
|
||||
});
|
||||
});
|
||||
service.deleteUntitledWorkspaceSync(workspace);
|
||||
});
|
||||
});
|
||||
|
||||
test('saveWorkspace (saved workspace, preserves forward slashes)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => {
|
||||
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
|
||||
const newWorkspaceConfigPath = path.join(os.tmpdir(), `mySavedWorkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
|
||||
test('rewriteWorkspaceFileForNewLocation (unc paths)', () => {
|
||||
if (!isWindows) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return service.saveWorkspaceAs(workspace, workspaceConfigPath).then(savedWorkspace => {
|
||||
const contents = fs.readFileSync(savedWorkspace.configPath).toString();
|
||||
fs.writeFileSync(savedWorkspace.configPath, contents.replace(/[\\]/g, '/')); // convert backslash to slash
|
||||
const workspaceLocation = path.join(os.tmpdir(), 'wsloc');
|
||||
const folder1Location = 'x:\\foo';
|
||||
const folder2Location = '\\\\server\\share2\\some\\path';
|
||||
const folder3Location = path.join(os.tmpdir(), 'wsloc', 'inner', 'more');
|
||||
|
||||
return service.saveWorkspaceAs(savedWorkspace, newWorkspaceConfigPath).then(newSavedWorkspace => {
|
||||
assert.ok(newSavedWorkspace.id);
|
||||
assert.notEqual(newSavedWorkspace.id, workspace.id);
|
||||
assertPathEquals(newSavedWorkspace.configPath, newWorkspaceConfigPath);
|
||||
return createWorkspace([folder1Location, folder2Location, folder3Location]).then(workspace => {
|
||||
const workspaceConfigPath = URI.file(path.join(workspaceLocation, `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`));
|
||||
let origContent = fs.readFileSync(workspace.configPath.fsPath).toString();
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(newSavedWorkspace.configPath).toString()) as IStoredWorkspace;
|
||||
assert.ok(ws.folders.every(f => (<IRawFileWorkspaceFolder>f).path.indexOf('\\') < 0));
|
||||
const newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath);
|
||||
|
||||
extfs.delSync(workspaceConfigPath);
|
||||
extfs.delSync(newWorkspaceConfigPath);
|
||||
});
|
||||
});
|
||||
const ws = JSON.parse(newContent) as IStoredWorkspace;
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, folder1Location);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, folder2Location);
|
||||
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[2]).path, 'inner\\more');
|
||||
|
||||
service.deleteUntitledWorkspaceSync(workspace);
|
||||
});
|
||||
});
|
||||
|
||||
test('deleteUntitledWorkspaceSync (untitled)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(fs.existsSync(workspace.configPath.fsPath));
|
||||
|
||||
service.deleteUntitledWorkspaceSync(workspace);
|
||||
|
||||
assert.ok(!fs.existsSync(workspace.configPath));
|
||||
assert.ok(!fs.existsSync(workspace.configPath.fsPath));
|
||||
});
|
||||
});
|
||||
|
||||
test('deleteUntitledWorkspaceSync (saved)', () => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
|
||||
|
||||
return service.saveWorkspaceAs(workspace, workspaceConfigPath).then(savedWorkspace => {
|
||||
assert.ok(fs.existsSync(savedWorkspace.configPath));
|
||||
|
||||
service.deleteUntitledWorkspaceSync(savedWorkspace);
|
||||
|
||||
assert.ok(fs.existsSync(savedWorkspace.configPath));
|
||||
});
|
||||
service.deleteUntitledWorkspaceSync(workspace);
|
||||
});
|
||||
});
|
||||
|
||||
test('getUntitledWorkspaceSync', () => {
|
||||
let untitled = service.getUntitledWorkspacesSync();
|
||||
assert.equal(0, untitled.length);
|
||||
assert.equal(untitled.length, 0);
|
||||
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(untitledOne => {
|
||||
assert.ok(fs.existsSync(untitledOne.configPath));
|
||||
assert.ok(fs.existsSync(untitledOne.configPath.fsPath));
|
||||
|
||||
untitled = service.getUntitledWorkspacesSync();
|
||||
|
||||
assert.equal(1, untitled.length);
|
||||
assert.equal(untitledOne.id, untitled[0].id);
|
||||
assert.equal(untitledOne.id, untitled[0].workspace.id);
|
||||
|
||||
return createWorkspace([os.tmpdir(), process.cwd()]).then(untitledTwo => {
|
||||
assert.ok(fs.existsSync(untitledTwo.configPath));
|
||||
assert.ok(fs.existsSync(untitledTwo.configPath.fsPath));
|
||||
|
||||
untitled = service.getUntitledWorkspacesSync();
|
||||
|
||||
if (untitled.length === 1) {
|
||||
assert.fail('Unexpected workspaces count, contents:\n' + fs.readFileSync(untitledTwo.configPath, 'utf8'));
|
||||
assert.fail('Unexpected workspaces count, contents:\n' + fs.readFileSync(untitledTwo.configPath.fsPath, 'utf8'));
|
||||
}
|
||||
|
||||
assert.equal(2, untitled.length);
|
||||
|
||||
Reference in New Issue
Block a user