mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-09 17:52:34 -05:00
Refresh master with initial release/0.24 snapshot (#332)
* Initial port of release/0.24 source code * Fix additional headers * Fix a typo in launch.json
This commit is contained in:
@@ -14,6 +14,8 @@ import { isLinux } from 'vs/base/common/platform';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import Event from 'vs/base/common/event';
|
||||
import { tildify, getPathLabel } from 'vs/base/common/labels';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import URI from 'vs/base/common/uri';
|
||||
|
||||
export const IWorkspacesMainService = createDecorator<IWorkspacesMainService>('workspacesMainService');
|
||||
export const IWorkspacesService = createDecorator<IWorkspacesService>('workspacesService');
|
||||
@@ -32,21 +34,54 @@ export interface IWorkspaceIdentifier {
|
||||
configPath: string;
|
||||
}
|
||||
|
||||
export interface IStoredWorkspaceFolder {
|
||||
export function isStoredWorkspaceFolder(thing: any): thing is IStoredWorkspaceFolder {
|
||||
return isRawFileWorkspaceFolder(thing) || isRawUriWorkspaceFolder(thing);
|
||||
}
|
||||
|
||||
export function isRawFileWorkspaceFolder(thing: any): thing is IRawFileWorkspaceFolder {
|
||||
return thing
|
||||
&& typeof thing === 'object'
|
||||
&& typeof thing.path === 'string'
|
||||
&& (!thing.name || typeof thing.name === 'string');
|
||||
}
|
||||
|
||||
export function isRawUriWorkspaceFolder(thing: any): thing is IRawUriWorkspaceFolder {
|
||||
return thing
|
||||
&& typeof thing === 'object'
|
||||
&& typeof thing.uri === 'string'
|
||||
&& (!thing.name || typeof thing.name === 'string');
|
||||
}
|
||||
|
||||
export interface IRawFileWorkspaceFolder {
|
||||
path: string;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export interface IRawUriWorkspaceFolder {
|
||||
uri: string;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export type IStoredWorkspaceFolder = IRawFileWorkspaceFolder | IRawUriWorkspaceFolder;
|
||||
|
||||
export interface IResolvedWorkspace extends IWorkspaceIdentifier {
|
||||
folders: IWorkspaceFolder[];
|
||||
}
|
||||
|
||||
export interface IStoredWorkspace {
|
||||
folders: IStoredWorkspaceFolder[];
|
||||
}
|
||||
|
||||
export interface IResolvedWorkspace extends IWorkspaceIdentifier, IStoredWorkspace { }
|
||||
|
||||
export interface IWorkspaceSavedEvent {
|
||||
workspace: IWorkspaceIdentifier;
|
||||
oldConfigPath: string;
|
||||
}
|
||||
|
||||
export interface IWorkspaceFolderCreationData {
|
||||
uri: URI;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export interface IWorkspacesMainService extends IWorkspacesService {
|
||||
_serviceBrand: any;
|
||||
|
||||
@@ -54,7 +89,8 @@ export interface IWorkspacesMainService extends IWorkspacesService {
|
||||
onUntitledWorkspaceDeleted: Event<IWorkspaceIdentifier>;
|
||||
|
||||
saveWorkspace(workspace: IWorkspaceIdentifier, target: string): TPromise<IWorkspaceIdentifier>;
|
||||
createWorkspaceSync(folders?: string[]): IWorkspaceIdentifier;
|
||||
|
||||
createWorkspaceSync(folders?: IWorkspaceFolderCreationData[]): IWorkspaceIdentifier;
|
||||
|
||||
resolveWorkspace(path: string): TPromise<IResolvedWorkspace>;
|
||||
resolveWorkspaceSync(path: string): IResolvedWorkspace;
|
||||
@@ -71,7 +107,7 @@ export interface IWorkspacesMainService extends IWorkspacesService {
|
||||
export interface IWorkspacesService {
|
||||
_serviceBrand: any;
|
||||
|
||||
createWorkspace(folders?: string[]): TPromise<IWorkspaceIdentifier>;
|
||||
createWorkspace(folders?: IWorkspaceFolderCreationData[]): TPromise<IWorkspaceIdentifier>;
|
||||
}
|
||||
|
||||
export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), environmentService: IEnvironmentService, options?: { verbose: boolean }): string {
|
||||
@@ -104,4 +140,4 @@ export function isWorkspaceIdentifier(obj: any): obj is IWorkspaceIdentifier {
|
||||
const workspaceIdentifier = obj as IWorkspaceIdentifier;
|
||||
|
||||
return workspaceIdentifier && typeof workspaceIdentifier.id === 'string' && typeof workspaceIdentifier.configPath === 'string';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,11 @@
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IWorkspacesService, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IWorkspacesService, IWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
|
||||
import URI from 'vs/base/common/uri';
|
||||
|
||||
export interface IWorkspacesChannel extends IChannel {
|
||||
call(command: 'createWorkspace', arg: [string[]]): TPromise<string>;
|
||||
call(command: 'createWorkspace', arg: [IWorkspaceFolderCreationData[]]): TPromise<string>;
|
||||
call(command: string, arg?: any): TPromise<any>;
|
||||
}
|
||||
|
||||
@@ -18,9 +19,22 @@ export class WorkspacesChannel implements IWorkspacesChannel {
|
||||
|
||||
constructor(private service: IWorkspacesService) { }
|
||||
|
||||
call(command: string, arg?: any): TPromise<any> {
|
||||
public call(command: string, arg?: any): TPromise<any> {
|
||||
switch (command) {
|
||||
case 'createWorkspace': return this.service.createWorkspace(arg);
|
||||
case 'createWorkspace': {
|
||||
const rawFolders: IWorkspaceFolderCreationData[] = arg;
|
||||
let folders: IWorkspaceFolderCreationData[];
|
||||
if (Array.isArray(rawFolders)) {
|
||||
folders = rawFolders.map(rawFolder => {
|
||||
return {
|
||||
uri: URI.revive(rawFolder.uri), // convert raw URI back to real URI
|
||||
name: rawFolder.name
|
||||
} as IWorkspaceFolderCreationData;
|
||||
});
|
||||
}
|
||||
|
||||
return this.service.createWorkspace(folders);
|
||||
};
|
||||
}
|
||||
|
||||
return void 0;
|
||||
@@ -33,7 +47,7 @@ export class WorkspacesChannelClient implements IWorkspacesService {
|
||||
|
||||
constructor(private channel: IWorkspacesChannel) { }
|
||||
|
||||
createWorkspace(folders?: string[]): TPromise<IWorkspaceIdentifier> {
|
||||
public createWorkspace(folders?: IWorkspaceFolderCreationData[]): TPromise<IWorkspaceIdentifier> {
|
||||
return this.channel.call('createWorkspace', folders);
|
||||
}
|
||||
}
|
||||
@@ -5,27 +5,29 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { IWorkspacesMainService, IWorkspaceIdentifier, IStoredWorkspace, WORKSPACE_EXTENSION, IWorkspaceSavedEvent, UNTITLED_WORKSPACE_NAME, IResolvedWorkspace } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IWorkspacesMainService, IWorkspaceIdentifier, WORKSPACE_EXTENSION, IWorkspaceSavedEvent, UNTITLED_WORKSPACE_NAME, IResolvedWorkspace, IStoredWorkspaceFolder, isRawFileWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { isParent } from 'vs/platform/files/common/files';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { extname, join, dirname, isAbsolute, resolve, relative } from 'path';
|
||||
import { extname, join, dirname, isAbsolute, resolve } from 'path';
|
||||
import { mkdirp, writeFile, readFile } from 'vs/base/node/pfs';
|
||||
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
||||
import { isLinux } from 'vs/base/common/platform';
|
||||
import { isLinux, isMacintosh } from 'vs/base/common/platform';
|
||||
import { delSync, readdirSync } from 'vs/base/node/extfs';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { isEqual, isEqualOrParent } from 'vs/base/common/paths';
|
||||
import { isEqual } from 'vs/base/common/paths';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { createHash } from 'crypto';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import * as json from 'vs/base/common/json';
|
||||
import * as jsonEdit from 'vs/base/common/jsonEdit';
|
||||
import { applyEdit } from 'vs/base/common/jsonFormatter';
|
||||
import { massageFolderPathForWorkspace } from 'vs/platform/workspaces/node/workspaces';
|
||||
import { toWorkspaceFolders } from 'vs/platform/workspace/common/workspace';
|
||||
import URI from 'vs/base/common/uri';
|
||||
|
||||
// TODO@Ben migration
|
||||
export interface ILegacyStoredWorkspace {
|
||||
id: string;
|
||||
folders: string[];
|
||||
export interface IStoredWorkspace {
|
||||
folders: IStoredWorkspaceFolder[];
|
||||
}
|
||||
|
||||
export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
@@ -68,7 +70,14 @@ export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
return null; // does not look like a valid workspace config file
|
||||
}
|
||||
|
||||
return this.doResolveWorkspace(path, readFileSync(path, 'utf8'));
|
||||
let contents: string;
|
||||
try {
|
||||
contents = readFileSync(path, 'utf8');
|
||||
} catch (error) {
|
||||
return null; // invalid workspace
|
||||
}
|
||||
|
||||
return this.doResolveWorkspace(path, contents);
|
||||
}
|
||||
|
||||
private isWorkspacePath(path: string): boolean {
|
||||
@@ -79,17 +88,10 @@ export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
try {
|
||||
const workspace = this.doParseStoredWorkspace(path, contents);
|
||||
|
||||
// relative paths get resolved against the workspace location
|
||||
workspace.folders.forEach(folder => {
|
||||
if (!isAbsolute(folder.path)) {
|
||||
folder.path = resolve(dirname(path), folder.path);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
id: this.getWorkspaceId(path),
|
||||
configPath: path,
|
||||
folders: workspace.folders
|
||||
folders: toWorkspaceFolders(workspace.folders, URI.file(dirname(path)))
|
||||
};
|
||||
} catch (error) {
|
||||
this.logService.log(error.toString());
|
||||
@@ -108,20 +110,13 @@ export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
throw new Error(`${path} cannot be parsed as JSON file (${error}).`);
|
||||
}
|
||||
|
||||
// TODO@Ben migration
|
||||
const legacyStoredWorkspace = (<any>storedWorkspace) as ILegacyStoredWorkspace;
|
||||
if (legacyStoredWorkspace.folders.some(folder => typeof folder === 'string')) {
|
||||
storedWorkspace.folders = legacyStoredWorkspace.folders.map(folder => ({ path: URI.parse(folder).fsPath }));
|
||||
writeFileSync(path, JSON.stringify(storedWorkspace, null, '\t'));
|
||||
}
|
||||
|
||||
// Filter out folders which do not have a path set
|
||||
// Filter out folders which do not have a path or uri set
|
||||
if (Array.isArray(storedWorkspace.folders)) {
|
||||
storedWorkspace.folders = storedWorkspace.folders.filter(folder => !!folder.path);
|
||||
storedWorkspace.folders = storedWorkspace.folders.filter(folder => isStoredWorkspaceFolder(folder));
|
||||
}
|
||||
|
||||
// Validate
|
||||
if (!Array.isArray(storedWorkspace.folders) || storedWorkspace.folders.length === 0) {
|
||||
if (!Array.isArray(storedWorkspace.folders)) {
|
||||
throw new Error(`${path} looks like an invalid workspace file.`);
|
||||
}
|
||||
|
||||
@@ -132,7 +127,7 @@ export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
return isParent(path, this.environmentService.workspacesHome, !isLinux /* ignore case */);
|
||||
}
|
||||
|
||||
public createWorkspace(folders: string[]): TPromise<IWorkspaceIdentifier> {
|
||||
public createWorkspace(folders?: IWorkspaceFolderCreationData[]): TPromise<IWorkspaceIdentifier> {
|
||||
const { workspace, configParent, storedWorkspace } = this.createUntitledWorkspace(folders);
|
||||
|
||||
return mkdirp(configParent).then(() => {
|
||||
@@ -140,7 +135,7 @@ export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
});
|
||||
}
|
||||
|
||||
public createWorkspaceSync(folders: string[]): IWorkspaceIdentifier {
|
||||
public createWorkspaceSync(folders?: IWorkspaceFolderCreationData[]): IWorkspaceIdentifier {
|
||||
const { workspace, configParent, storedWorkspace } = this.createUntitledWorkspace(folders);
|
||||
|
||||
if (!existsSync(this.workspacesHome)) {
|
||||
@@ -154,15 +149,32 @@ export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
return workspace;
|
||||
}
|
||||
|
||||
private createUntitledWorkspace(folders: string[]): { workspace: IWorkspaceIdentifier, configParent: string, storedWorkspace: IStoredWorkspace } {
|
||||
private createUntitledWorkspace(folders: IWorkspaceFolderCreationData[] = []): { workspace: IWorkspaceIdentifier, configParent: string, 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 storedWorkspace: IStoredWorkspace = {
|
||||
folders: folders.map(folder => ({
|
||||
path: folder
|
||||
}))
|
||||
folders: folders.map(folder => {
|
||||
const folderResource = folder.uri;
|
||||
let storedWorkspace: IStoredWorkspaceFolder;
|
||||
|
||||
// File URI
|
||||
if (folderResource.scheme === 'file') {
|
||||
storedWorkspace = { path: massageFolderPathForWorkspace(folderResource.fsPath, untitledWorkspaceConfigFolder, []) };
|
||||
}
|
||||
|
||||
// Any URI
|
||||
else {
|
||||
storedWorkspace = { uri: folderResource.toString(true) };
|
||||
}
|
||||
|
||||
if (folder.name) {
|
||||
storedWorkspace.name = folder.name;
|
||||
}
|
||||
|
||||
return storedWorkspace;
|
||||
})
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -195,10 +207,11 @@ export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
}
|
||||
|
||||
// Read the contents of the workspace file and resolve it
|
||||
return readFile(workspace.configPath).then(rawWorkspaceContents => {
|
||||
return readFile(workspace.configPath).then(raw => {
|
||||
const rawWorkspaceContents = raw.toString();
|
||||
let storedWorkspace: IStoredWorkspace;
|
||||
try {
|
||||
storedWorkspace = this.doParseStoredWorkspace(workspace.configPath, rawWorkspaceContents.toString());
|
||||
storedWorkspace = this.doParseStoredWorkspace(workspace.configPath, rawWorkspaceContents);
|
||||
} catch (error) {
|
||||
return TPromise.wrapError(error);
|
||||
}
|
||||
@@ -210,16 +223,24 @@ export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
// is a parent of the location of the workspace file itself. Otherwise keep
|
||||
// using absolute paths.
|
||||
storedWorkspace.folders.forEach(folder => {
|
||||
if (!isAbsolute(folder.path)) {
|
||||
folder.path = resolve(sourceConfigFolder, folder.path); // relative paths get resolved against the workspace location
|
||||
if (isRawFileWorkspaceFolder(folder)) {
|
||||
if (!isAbsolute(folder.path)) {
|
||||
folder.path = resolve(sourceConfigFolder, folder.path); // relative paths get resolved against the workspace location
|
||||
}
|
||||
folder.path = massageFolderPathForWorkspace(folder.path, targetConfigFolder, storedWorkspace.folders);
|
||||
}
|
||||
|
||||
if (isEqualOrParent(folder.path, targetConfigFolder, !isLinux)) {
|
||||
folder.path = relative(targetConfigFolder, folder.path) || '.'; // absolute paths get converted to relative ones to workspace location if possible
|
||||
}
|
||||
});
|
||||
|
||||
return writeFile(targetConfigPath, JSON.stringify(storedWorkspace, null, '\t')).then(() => {
|
||||
// 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 = applyEdit(rawWorkspaceContents, edit);
|
||||
});
|
||||
|
||||
return writeFile(targetConfigPath, newRawWorkspaceContents).then(() => {
|
||||
const savedWorkspaceIdentifier = { id: this.getWorkspaceId(targetConfigPath), configPath: targetConfigPath };
|
||||
|
||||
// Event
|
||||
|
||||
66
src/vs/platform/workspaces/node/workspaces.ts
Normal file
66
src/vs/platform/workspaces/node/workspaces.ts
Normal 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.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { IStoredWorkspaceFolder, isRawFileWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { isWindows, isLinux } from 'vs/base/common/platform';
|
||||
import { isAbsolute, relative } from 'path';
|
||||
import { isEqualOrParent, normalize } from 'vs/base/common/paths';
|
||||
import { normalizeDriveLetter } from 'vs/base/common/labels';
|
||||
|
||||
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, targetConfigFolder: string, existingFolders: IStoredWorkspaceFolder[]): string {
|
||||
const useSlashesForPath = shouldUseSlashForPath(existingFolders);
|
||||
|
||||
// Convert path to relative path if the target config folder
|
||||
// is a parent of the path.
|
||||
if (isEqualOrParent(absoluteFolderPath, targetConfigFolder, !isLinux)) {
|
||||
absoluteFolderPath = relative(targetConfigFolder, 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 (useSlashesForPath) {
|
||||
absoluteFolderPath = normalize(absoluteFolderPath, false /* do not use OS path separator */);
|
||||
}
|
||||
|
||||
absoluteFolderPath = normalizeDriveLetter(absoluteFolderPath);
|
||||
} else if (useSlashesForPath) {
|
||||
absoluteFolderPath = absoluteFolderPath.replace(/[\\]/g, SLASH);
|
||||
}
|
||||
}
|
||||
|
||||
return absoluteFolderPath;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -13,13 +13,14 @@ import extfs = require('vs/base/node/extfs');
|
||||
import pfs = require('vs/base/node/pfs');
|
||||
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import { parseArgs } from 'vs/platform/environment/node/argv';
|
||||
import { WorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService';
|
||||
import { IStoredWorkspace, WORKSPACE_EXTENSION, IWorkspaceSavedEvent, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { WorkspacesMainService, IStoredWorkspace } from 'vs/platform/workspaces/electron-main/workspacesMainService';
|
||||
import { WORKSPACE_EXTENSION, IWorkspaceSavedEvent, IWorkspaceIdentifier, IRawFileWorkspaceFolder, IWorkspaceFolderCreationData, IRawUriWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { LogMainService } from 'vs/platform/log/common/log';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { getRandomTestPath } from 'vs/workbench/test/workbenchTestServices';
|
||||
|
||||
suite('WorkspacesMainService', () => {
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', 'service');
|
||||
const parentDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'workspacesservice');
|
||||
const workspacesHome = path.join(parentDir, 'Workspaces');
|
||||
|
||||
class TestEnvironmentService extends EnvironmentService {
|
||||
@@ -38,6 +39,14 @@ suite('WorkspacesMainService', () => {
|
||||
}
|
||||
}
|
||||
|
||||
function createWorkspace(folders: string[], names?: string[]) {
|
||||
return service.createWorkspace(folders.map((folder, index) => ({ uri: URI.file(folder), name: names ? names[index] : void 0 } as IWorkspaceFolderCreationData)));
|
||||
}
|
||||
|
||||
function createWorkspaceSync(folders: string[], names?: string[]) {
|
||||
return service.createWorkspaceSync(folders.map((folder, index) => ({ uri: URI.file(folder), name: names ? names[index] : void 0 } as IWorkspaceFolderCreationData)));
|
||||
}
|
||||
|
||||
const environmentService = new TestEnvironmentService(parseArgs(process.argv), process.execPath);
|
||||
const logService = new LogMainService(environmentService);
|
||||
|
||||
@@ -59,34 +68,104 @@ suite('WorkspacesMainService', () => {
|
||||
});
|
||||
|
||||
test('createWorkspace (folders)', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
assert.ok(workspace);
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 2); //
|
||||
assert.equal(ws.folders[0].path, process.cwd());
|
||||
assert.equal(ws.folders[1].path, os.tmpdir());
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd());
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[1]).path, os.tmpdir());
|
||||
|
||||
assert.ok(!(<IRawFileWorkspaceFolder>ws.folders[0]).name);
|
||||
assert.ok(!(<IRawFileWorkspaceFolder>ws.folders[1]).name);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('createWorkspace (folders with name)', done => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()], ['currentworkingdirectory', 'tempdir']).then(workspace => {
|
||||
assert.ok(workspace);
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 2); //
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd());
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[1]).path, os.tmpdir());
|
||||
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[0]).name, 'currentworkingdirectory');
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[1]).name, 'tempdir');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('createWorkspace (folders as other resource URIs)', () => {
|
||||
return service.createWorkspace([{ uri: URI.from({ scheme: 'myScheme', path: process.cwd() }) }, { uri: URI.from({ scheme: 'myScheme', path: os.tmpdir() }) }]).then(workspace => {
|
||||
assert.ok(workspace);
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).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.ok(!(<IRawFileWorkspaceFolder>ws.folders[0]).name);
|
||||
assert.ok(!(<IRawFileWorkspaceFolder>ws.folders[1]).name);
|
||||
});
|
||||
});
|
||||
|
||||
test('createWorkspaceSync (folders)', () => {
|
||||
const workspace = service.createWorkspaceSync([process.cwd(), os.tmpdir()]);
|
||||
const workspace = createWorkspaceSync([process.cwd(), os.tmpdir()]);
|
||||
assert.ok(workspace);
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 2); //
|
||||
assert.equal(ws.folders[0].path, process.cwd());
|
||||
assert.equal(ws.folders[1].path, os.tmpdir());
|
||||
assert.equal(ws.folders.length, 2);
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd());
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[1]).path, os.tmpdir());
|
||||
|
||||
assert.ok(!(<IRawFileWorkspaceFolder>ws.folders[0]).name);
|
||||
assert.ok(!(<IRawFileWorkspaceFolder>ws.folders[1]).name);
|
||||
});
|
||||
|
||||
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(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 2);
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd());
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[1]).path, os.tmpdir());
|
||||
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[0]).name, 'currentworkingdirectory');
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[1]).name, 'tempdir');
|
||||
});
|
||||
|
||||
test('createWorkspaceSync (folders as other resource URIs)', () => {
|
||||
const workspace = service.createWorkspaceSync([{ uri: URI.from({ scheme: 'myScheme', path: process.cwd() }) }, { uri: URI.from({ scheme: 'myScheme', path: os.tmpdir() }) }]);
|
||||
assert.ok(workspace);
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
assert.ok(service.isUntitledWorkspace(workspace));
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(workspace.configPath).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.ok(!(<IRawFileWorkspaceFolder>ws.folders[0]).name);
|
||||
assert.ok(!(<IRawFileWorkspaceFolder>ws.folders[1]).name);
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
assert.ok(service.resolveWorkspaceSync(workspace.configPath));
|
||||
|
||||
// make it a valid workspace path
|
||||
@@ -108,7 +187,7 @@ suite('WorkspacesMainService', () => {
|
||||
});
|
||||
|
||||
test('resolveWorkspace', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
return service.resolveWorkspace(workspace.configPath).then(ws => {
|
||||
assert.ok(ws);
|
||||
|
||||
@@ -134,44 +213,44 @@ suite('WorkspacesMainService', () => {
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support relative paths)', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib' }] }));
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(URI.file(resolved.folders[0].path).fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
assert.equal(resolved.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support relative paths #2)', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib/../other' }] }));
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(URI.file(resolved.folders[0].path).fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'other')).fsPath);
|
||||
assert.equal(resolved.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'other')).fsPath);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support relative paths #3)', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: 'ticino-playground/lib' }] }));
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(URI.file(resolved.folders[0].path).fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
assert.equal(resolved.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support invalid JSON via fault tolerant parsing)', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
fs.writeFileSync(workspace.configPath, '{ "folders": [ { "path": "./ticino-playground/lib" } , ] }'); // trailing comma
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(URI.file(resolved.folders[0].path).fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
assert.equal(resolved.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
|
||||
done();
|
||||
});
|
||||
@@ -188,7 +267,7 @@ suite('WorkspacesMainService', () => {
|
||||
deletedEvent = e;
|
||||
});
|
||||
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => {
|
||||
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
|
||||
|
||||
return service.saveWorkspace(workspace, workspaceConfigPath).then(savedWorkspace => {
|
||||
@@ -200,9 +279,9 @@ suite('WorkspacesMainService', () => {
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(savedWorkspace.configPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 3);
|
||||
assert.equal(ws.folders[0].path, process.cwd()); // absolute
|
||||
assert.equal(ws.folders[1].path, '.'); // relative
|
||||
assert.equal(ws.folders[2].path, path.relative(path.dirname(workspaceConfigPath), path.join(os.tmpdir(), 'somefolder'))); // relative
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd()); // absolute
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[1]).path, '.'); // relative
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[2]).path, path.relative(path.dirname(workspaceConfigPath), path.join(os.tmpdir(), 'somefolder'))); // relative
|
||||
|
||||
assert.equal(savedWorkspace, savedEvent.workspace);
|
||||
assert.equal(workspace.configPath, savedEvent.oldConfigPath);
|
||||
@@ -220,7 +299,7 @@ suite('WorkspacesMainService', () => {
|
||||
});
|
||||
|
||||
test('saveWorkspace (saved workspace)', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => {
|
||||
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}`);
|
||||
|
||||
@@ -232,9 +311,61 @@ suite('WorkspacesMainService', () => {
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(newSavedWorkspace.configPath).toString()) as IStoredWorkspace;
|
||||
assert.equal(ws.folders.length, 3);
|
||||
assert.equal(ws.folders[0].path, process.cwd()); // absolute path because outside of tmpdir
|
||||
assert.equal(ws.folders[1].path, '.'); // relative path because inside of tmpdir
|
||||
assert.equal(ws.folders[2].path, path.relative(path.dirname(workspaceConfigPath), path.join(os.tmpdir(), 'somefolder'))); // relative
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[0]).path, process.cwd()); // absolute path because outside of tmpdir
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[1]).path, '.'); // relative path because inside of tmpdir
|
||||
assert.equal((<IRawFileWorkspaceFolder>ws.folders[2]).path, path.relative(path.dirname(workspaceConfigPath), path.join(os.tmpdir(), 'somefolder'))); // relative
|
||||
|
||||
extfs.delSync(workspaceConfigPath);
|
||||
extfs.delSync(newWorkspaceConfigPath);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('saveWorkspace (saved workspace, preserves comments)', done => {
|
||||
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}`);
|
||||
|
||||
return service.saveWorkspace(workspace, workspaceConfigPath).then(savedWorkspace => {
|
||||
const contents = fs.readFileSync(savedWorkspace.configPath).toString();
|
||||
fs.writeFileSync(savedWorkspace.configPath, `// this is a comment\n${contents}`);
|
||||
|
||||
return service.saveWorkspace(savedWorkspace, newWorkspaceConfigPath).then(newSavedWorkspace => {
|
||||
assert.ok(newSavedWorkspace.id);
|
||||
assert.notEqual(newSavedWorkspace.id, workspace.id);
|
||||
assert.equal(newSavedWorkspace.configPath, newWorkspaceConfigPath);
|
||||
|
||||
const savedContents = fs.readFileSync(newSavedWorkspace.configPath).toString();
|
||||
assert.equal(0, savedContents.indexOf('// this is a comment'));
|
||||
|
||||
extfs.delSync(workspaceConfigPath);
|
||||
extfs.delSync(newWorkspaceConfigPath);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('saveWorkspace (saved workspace, preserves forward slashes)', done => {
|
||||
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}`);
|
||||
|
||||
return service.saveWorkspace(workspace, workspaceConfigPath).then(savedWorkspace => {
|
||||
const contents = fs.readFileSync(savedWorkspace.configPath).toString();
|
||||
fs.writeFileSync(savedWorkspace.configPath, contents.replace(/[\\]/g, '/')); // convert backslash to slash
|
||||
|
||||
return service.saveWorkspace(savedWorkspace, newWorkspaceConfigPath).then(newSavedWorkspace => {
|
||||
assert.ok(newSavedWorkspace.id);
|
||||
assert.notEqual(newSavedWorkspace.id, workspace.id);
|
||||
assert.equal(newSavedWorkspace.configPath, newWorkspaceConfigPath);
|
||||
|
||||
const ws = JSON.parse(fs.readFileSync(newSavedWorkspace.configPath).toString()) as IStoredWorkspace;
|
||||
assert.ok(ws.folders.every(f => (<IRawFileWorkspaceFolder>f).path.indexOf('\\') < 0));
|
||||
|
||||
extfs.delSync(workspaceConfigPath);
|
||||
extfs.delSync(newWorkspaceConfigPath);
|
||||
@@ -246,7 +377,7 @@ suite('WorkspacesMainService', () => {
|
||||
});
|
||||
|
||||
test('deleteUntitledWorkspaceSync (untitled)', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
|
||||
service.deleteUntitledWorkspaceSync(workspace);
|
||||
@@ -258,7 +389,7 @@ suite('WorkspacesMainService', () => {
|
||||
});
|
||||
|
||||
test('deleteUntitledWorkspaceSync (saved)', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
|
||||
|
||||
return service.saveWorkspace(workspace, workspaceConfigPath).then(savedWorkspace => {
|
||||
@@ -277,20 +408,22 @@ suite('WorkspacesMainService', () => {
|
||||
let untitled = service.getUntitledWorkspacesSync();
|
||||
assert.equal(0, untitled.length);
|
||||
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(untitledOne => {
|
||||
return createWorkspace([process.cwd(), os.tmpdir()]).then(untitledOne => {
|
||||
untitled = service.getUntitledWorkspacesSync();
|
||||
|
||||
assert.equal(1, untitled.length);
|
||||
assert.equal(untitledOne.id, untitled[0].id);
|
||||
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(untitledTwo => {
|
||||
return createWorkspace([os.tmpdir(), process.cwd()]).then(untitledTwo => {
|
||||
untitled = service.getUntitledWorkspacesSync();
|
||||
|
||||
assert.equal(2, untitled.length);
|
||||
|
||||
service.deleteUntitledWorkspaceSync(untitledOne);
|
||||
service.deleteUntitledWorkspaceSync(untitledTwo);
|
||||
untitled = service.getUntitledWorkspacesSync();
|
||||
assert.equal(1, untitled.length);
|
||||
|
||||
service.deleteUntitledWorkspaceSync(untitledTwo);
|
||||
untitled = service.getUntitledWorkspacesSync();
|
||||
assert.equal(0, untitled.length);
|
||||
|
||||
@@ -298,4 +431,4 @@ suite('WorkspacesMainService', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user