mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-31 09:35:39 -05:00
SQL Operations Studio Public Preview 1 (0.23) release source code
This commit is contained in:
107
src/vs/platform/workspaces/common/workspaces.ts
Normal file
107
src/vs/platform/workspaces/common/workspaces.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { isParent } from 'vs/platform/files/common/files';
|
||||
import { localize } from 'vs/nls';
|
||||
import { basename, dirname, join } from 'vs/base/common/paths';
|
||||
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';
|
||||
|
||||
export const IWorkspacesMainService = createDecorator<IWorkspacesMainService>('workspacesMainService');
|
||||
export const IWorkspacesService = createDecorator<IWorkspacesService>('workspacesService');
|
||||
|
||||
export const WORKSPACE_EXTENSION = 'code-workspace';
|
||||
export const WORKSPACE_FILTER = [{ name: localize('codeWorkspace', "Code Workspace"), extensions: [WORKSPACE_EXTENSION] }];
|
||||
export const UNTITLED_WORKSPACE_NAME = 'workspace.json';
|
||||
|
||||
/**
|
||||
* A single folder workspace identifier is just the path to the folder.
|
||||
*/
|
||||
export type ISingleFolderWorkspaceIdentifier = string;
|
||||
|
||||
export interface IWorkspaceIdentifier {
|
||||
id: string;
|
||||
configPath: string;
|
||||
}
|
||||
|
||||
export interface IStoredWorkspaceFolder {
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface IStoredWorkspace {
|
||||
folders: IStoredWorkspaceFolder[];
|
||||
}
|
||||
|
||||
export interface IResolvedWorkspace extends IWorkspaceIdentifier, IStoredWorkspace { }
|
||||
|
||||
export interface IWorkspaceSavedEvent {
|
||||
workspace: IWorkspaceIdentifier;
|
||||
oldConfigPath: string;
|
||||
}
|
||||
|
||||
export interface IWorkspacesMainService extends IWorkspacesService {
|
||||
_serviceBrand: any;
|
||||
|
||||
onWorkspaceSaved: Event<IWorkspaceSavedEvent>;
|
||||
onUntitledWorkspaceDeleted: Event<IWorkspaceIdentifier>;
|
||||
|
||||
saveWorkspace(workspace: IWorkspaceIdentifier, target: string): TPromise<IWorkspaceIdentifier>;
|
||||
createWorkspaceSync(folders?: string[]): IWorkspaceIdentifier;
|
||||
|
||||
resolveWorkspace(path: string): TPromise<IResolvedWorkspace>;
|
||||
resolveWorkspaceSync(path: string): IResolvedWorkspace;
|
||||
|
||||
isUntitledWorkspace(workspace: IWorkspaceIdentifier): boolean;
|
||||
|
||||
deleteUntitledWorkspaceSync(workspace: IWorkspaceIdentifier): void;
|
||||
|
||||
getUntitledWorkspacesSync(): IWorkspaceIdentifier[];
|
||||
|
||||
getWorkspaceId(workspacePath: string): string;
|
||||
}
|
||||
|
||||
export interface IWorkspacesService {
|
||||
_serviceBrand: any;
|
||||
|
||||
createWorkspace(folders?: string[]): TPromise<IWorkspaceIdentifier>;
|
||||
}
|
||||
|
||||
export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), environmentService: IEnvironmentService, options?: { verbose: boolean }): string {
|
||||
|
||||
// Workspace: Single Folder
|
||||
if (isSingleFolderWorkspaceIdentifier(workspace)) {
|
||||
return tildify(workspace, environmentService.userHome);
|
||||
}
|
||||
|
||||
// Workspace: Untitled
|
||||
if (isParent(workspace.configPath, environmentService.workspacesHome, !isLinux /* ignore case */)) {
|
||||
return localize('untitledWorkspace', "Untitled (Workspace)");
|
||||
}
|
||||
|
||||
// Workspace: Saved
|
||||
const filename = basename(workspace.configPath);
|
||||
const workspaceName = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1);
|
||||
if (options && options.verbose) {
|
||||
return localize('workspaceNameVerbose', "{0} (Workspace)", getPathLabel(join(dirname(workspace.configPath), workspaceName), null, environmentService));
|
||||
}
|
||||
|
||||
return localize('workspaceName', "{0} (Workspace)", workspaceName);
|
||||
}
|
||||
|
||||
export function isSingleFolderWorkspaceIdentifier(obj: any): obj is ISingleFolderWorkspaceIdentifier {
|
||||
return typeof obj === 'string';
|
||||
}
|
||||
|
||||
export function isWorkspaceIdentifier(obj: any): obj is IWorkspaceIdentifier {
|
||||
const workspaceIdentifier = obj as IWorkspaceIdentifier;
|
||||
|
||||
return workspaceIdentifier && typeof workspaceIdentifier.id === 'string' && typeof workspaceIdentifier.configPath === 'string';
|
||||
}
|
||||
39
src/vs/platform/workspaces/common/workspacesIpc.ts
Normal file
39
src/vs/platform/workspaces/common/workspacesIpc.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { 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';
|
||||
|
||||
export interface IWorkspacesChannel extends IChannel {
|
||||
call(command: 'createWorkspace', arg: [string[]]): TPromise<string>;
|
||||
call(command: string, arg?: any): TPromise<any>;
|
||||
}
|
||||
|
||||
export class WorkspacesChannel implements IWorkspacesChannel {
|
||||
|
||||
constructor(private service: IWorkspacesService) { }
|
||||
|
||||
call(command: string, arg?: any): TPromise<any> {
|
||||
switch (command) {
|
||||
case 'createWorkspace': return this.service.createWorkspace(arg);
|
||||
}
|
||||
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkspacesChannelClient implements IWorkspacesService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
constructor(private channel: IWorkspacesChannel) { }
|
||||
|
||||
createWorkspace(folders?: string[]): TPromise<IWorkspaceIdentifier> {
|
||||
return this.channel.call('createWorkspace', folders);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { IWorkspacesMainService, IWorkspaceIdentifier, IStoredWorkspace, WORKSPACE_EXTENSION, IWorkspaceSavedEvent, UNTITLED_WORKSPACE_NAME, IResolvedWorkspace } 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 { mkdirp, writeFile, readFile } from 'vs/base/node/pfs';
|
||||
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
||||
import { isLinux } 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 { 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';
|
||||
|
||||
// TODO@Ben migration
|
||||
export interface ILegacyStoredWorkspace {
|
||||
id: string;
|
||||
folders: string[];
|
||||
}
|
||||
|
||||
export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
|
||||
public _serviceBrand: any;
|
||||
|
||||
protected workspacesHome: string;
|
||||
|
||||
private _onWorkspaceSaved: Emitter<IWorkspaceSavedEvent>;
|
||||
private _onUntitledWorkspaceDeleted: Emitter<IWorkspaceIdentifier>;
|
||||
|
||||
constructor(
|
||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||
@ILogService private logService: ILogService
|
||||
) {
|
||||
this.workspacesHome = environmentService.workspacesHome;
|
||||
|
||||
this._onWorkspaceSaved = new Emitter<IWorkspaceSavedEvent>();
|
||||
this._onUntitledWorkspaceDeleted = new Emitter<IWorkspaceIdentifier>();
|
||||
}
|
||||
|
||||
public get onWorkspaceSaved(): Event<IWorkspaceSavedEvent> {
|
||||
return this._onWorkspaceSaved.event;
|
||||
}
|
||||
|
||||
public get onUntitledWorkspaceDeleted(): Event<IWorkspaceIdentifier> {
|
||||
return this._onUntitledWorkspaceDeleted.event;
|
||||
}
|
||||
|
||||
public resolveWorkspace(path: string): TPromise<IResolvedWorkspace> {
|
||||
if (!this.isWorkspacePath(path)) {
|
||||
return TPromise.as(null); // does not look like a valid workspace config file
|
||||
}
|
||||
|
||||
return readFile(path).then(contents => this.doResolveWorkspace(path, contents.toString()));
|
||||
}
|
||||
|
||||
public resolveWorkspaceSync(path: string): IResolvedWorkspace {
|
||||
if (!this.isWorkspacePath(path)) {
|
||||
return null; // does not look like a valid workspace config file
|
||||
}
|
||||
|
||||
return this.doResolveWorkspace(path, readFileSync(path, 'utf8'));
|
||||
}
|
||||
|
||||
private isWorkspacePath(path: string): boolean {
|
||||
return this.isInsideWorkspacesHome(path) || extname(path) === `.${WORKSPACE_EXTENSION}`;
|
||||
}
|
||||
|
||||
private doResolveWorkspace(path: string, contents: string): IResolvedWorkspace {
|
||||
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
|
||||
};
|
||||
} catch (error) {
|
||||
this.logService.log(error.toString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private doParseStoredWorkspace(path: string, contents: string): IStoredWorkspace {
|
||||
|
||||
// Parse workspace file
|
||||
let storedWorkspace: IStoredWorkspace;
|
||||
try {
|
||||
storedWorkspace = json.parse(contents); // use fault tolerant parser
|
||||
} catch (error) {
|
||||
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
|
||||
if (Array.isArray(storedWorkspace.folders)) {
|
||||
storedWorkspace.folders = storedWorkspace.folders.filter(folder => !!folder.path);
|
||||
}
|
||||
|
||||
// Validate
|
||||
if (!Array.isArray(storedWorkspace.folders) || storedWorkspace.folders.length === 0) {
|
||||
throw new Error(`${path} looks like an invalid workspace file.`);
|
||||
}
|
||||
|
||||
return storedWorkspace;
|
||||
}
|
||||
|
||||
private isInsideWorkspacesHome(path: string): boolean {
|
||||
return isParent(path, this.environmentService.workspacesHome, !isLinux /* ignore case */);
|
||||
}
|
||||
|
||||
public createWorkspace(folders: string[]): TPromise<IWorkspaceIdentifier> {
|
||||
const { workspace, configParent, storedWorkspace } = this.createUntitledWorkspace(folders);
|
||||
|
||||
return mkdirp(configParent).then(() => {
|
||||
return writeFile(workspace.configPath, JSON.stringify(storedWorkspace, null, '\t')).then(() => workspace);
|
||||
});
|
||||
}
|
||||
|
||||
public createWorkspaceSync(folders: string[]): IWorkspaceIdentifier {
|
||||
const { workspace, configParent, storedWorkspace } = this.createUntitledWorkspace(folders);
|
||||
|
||||
if (!existsSync(this.workspacesHome)) {
|
||||
mkdirSync(this.workspacesHome);
|
||||
}
|
||||
|
||||
mkdirSync(configParent);
|
||||
|
||||
writeFileSync(workspace.configPath, JSON.stringify(storedWorkspace, null, '\t'));
|
||||
|
||||
return workspace;
|
||||
}
|
||||
|
||||
private createUntitledWorkspace(folders: string[]): { 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
|
||||
}))
|
||||
};
|
||||
|
||||
return {
|
||||
workspace: {
|
||||
id: this.getWorkspaceId(untitledWorkspaceConfigPath),
|
||||
configPath: untitledWorkspaceConfigPath
|
||||
},
|
||||
configParent: untitledWorkspaceConfigFolder,
|
||||
storedWorkspace
|
||||
};
|
||||
}
|
||||
|
||||
public getWorkspaceId(workspaceConfigPath: string): string {
|
||||
if (!isLinux) {
|
||||
workspaceConfigPath = workspaceConfigPath.toLowerCase(); // sanitize for platform file system
|
||||
}
|
||||
|
||||
return createHash('md5').update(workspaceConfigPath).digest('hex');
|
||||
}
|
||||
|
||||
public isUntitledWorkspace(workspace: IWorkspaceIdentifier): boolean {
|
||||
return this.isInsideWorkspacesHome(workspace.configPath);
|
||||
}
|
||||
|
||||
public saveWorkspace(workspace: IWorkspaceIdentifier, targetConfigPath: string): TPromise<IWorkspaceIdentifier> {
|
||||
|
||||
// Return early if target is same as source
|
||||
if (isEqual(workspace.configPath, targetConfigPath, !isLinux)) {
|
||||
return TPromise.as(workspace);
|
||||
}
|
||||
|
||||
// Read the contents of the workspace file and resolve it
|
||||
return readFile(workspace.configPath).then(rawWorkspaceContents => {
|
||||
let storedWorkspace: IStoredWorkspace;
|
||||
try {
|
||||
storedWorkspace = this.doParseStoredWorkspace(workspace.configPath, rawWorkspaceContents.toString());
|
||||
} catch (error) {
|
||||
return TPromise.wrapError(error);
|
||||
}
|
||||
|
||||
const sourceConfigFolder = dirname(workspace.configPath);
|
||||
const targetConfigFolder = dirname(targetConfigPath);
|
||||
|
||||
// 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.
|
||||
storedWorkspace.folders.forEach(folder => {
|
||||
if (!isAbsolute(folder.path)) {
|
||||
folder.path = resolve(sourceConfigFolder, folder.path); // relative paths get resolved against the workspace location
|
||||
}
|
||||
|
||||
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(() => {
|
||||
const savedWorkspaceIdentifier = { id: this.getWorkspaceId(targetConfigPath), configPath: targetConfigPath };
|
||||
|
||||
// Event
|
||||
this._onWorkspaceSaved.fire({ workspace: savedWorkspaceIdentifier, oldConfigPath: workspace.configPath });
|
||||
|
||||
// Delete untitled workspace
|
||||
this.deleteUntitledWorkspaceSync(workspace);
|
||||
|
||||
return savedWorkspaceIdentifier;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public deleteUntitledWorkspaceSync(workspace: IWorkspaceIdentifier): void {
|
||||
if (!this.isUntitledWorkspace(workspace)) {
|
||||
return; // only supported for untitled workspaces
|
||||
}
|
||||
|
||||
// Delete from disk
|
||||
this.doDeleteUntitledWorkspaceSync(workspace.configPath);
|
||||
|
||||
// Event
|
||||
this._onUntitledWorkspaceDeleted.fire(workspace);
|
||||
}
|
||||
|
||||
private doDeleteUntitledWorkspaceSync(configPath: string): void {
|
||||
try {
|
||||
delSync(dirname(configPath));
|
||||
} catch (error) {
|
||||
this.logService.log(`Unable to delete untitled workspace ${configPath} (${error}).`);
|
||||
}
|
||||
}
|
||||
|
||||
public getUntitledWorkspacesSync(): IWorkspaceIdentifier[] {
|
||||
let untitledWorkspacePaths: string[] = [];
|
||||
try {
|
||||
untitledWorkspacePaths = readdirSync(this.workspacesHome).map(folder => join(this.workspacesHome, folder, UNTITLED_WORKSPACE_NAME));
|
||||
} catch (error) {
|
||||
this.logService.log(`Unable to read folders in ${this.workspacesHome} (${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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 * as assert from 'assert';
|
||||
import fs = require('fs');
|
||||
import os = require('os');
|
||||
import path = require('path');
|
||||
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 { LogMainService } from 'vs/platform/log/common/log';
|
||||
import URI from 'vs/base/common/uri';
|
||||
|
||||
suite('WorkspacesMainService', () => {
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', 'service');
|
||||
const workspacesHome = path.join(parentDir, 'Workspaces');
|
||||
|
||||
class TestEnvironmentService extends EnvironmentService {
|
||||
get workspacesHome(): string {
|
||||
return workspacesHome;
|
||||
}
|
||||
}
|
||||
|
||||
class TestWorkspacesMainService extends WorkspacesMainService {
|
||||
public deleteWorkspaceCall: IWorkspaceIdentifier;
|
||||
|
||||
public deleteUntitledWorkspaceSync(workspace: IWorkspaceIdentifier): void {
|
||||
this.deleteWorkspaceCall = workspace;
|
||||
|
||||
super.deleteUntitledWorkspaceSync(workspace);
|
||||
}
|
||||
}
|
||||
|
||||
const environmentService = new TestEnvironmentService(parseArgs(process.argv), process.execPath);
|
||||
const logService = new LogMainService(environmentService);
|
||||
|
||||
let service: TestWorkspacesMainService;
|
||||
|
||||
setup(done => {
|
||||
service = new TestWorkspacesMainService(environmentService, logService);
|
||||
|
||||
// Delete any existing backups completely and then re-create it.
|
||||
extfs.del(workspacesHome, os.tmpdir(), () => {
|
||||
pfs.mkdirp(workspacesHome).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
teardown(done => {
|
||||
extfs.del(workspacesHome, os.tmpdir(), done);
|
||||
});
|
||||
|
||||
test('createWorkspace (folders)', done => {
|
||||
return service.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());
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('createWorkspaceSync (folders)', () => {
|
||||
const workspace = service.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());
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
assert.ok(service.resolveWorkspaceSync(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 resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(2, resolved.folders.length);
|
||||
assert.equal(resolved.configPath, workspace.configPath);
|
||||
assert.ok(resolved.id);
|
||||
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ something: 'something' })); // invalid workspace
|
||||
const resolvedInvalid = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.ok(!resolvedInvalid);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspace', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
return service.resolveWorkspace(workspace.configPath).then(ws => {
|
||||
assert.ok(ws);
|
||||
|
||||
// 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;
|
||||
|
||||
return service.resolveWorkspace(workspace.configPath).then(resolved => {
|
||||
assert.equal(2, resolved.folders.length);
|
||||
assert.equal(resolved.configPath, workspace.configPath);
|
||||
assert.ok(resolved.id);
|
||||
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ something: 'something' })); // invalid workspace
|
||||
return service.resolveWorkspace(workspace.configPath).then(resolvedInvalid => {
|
||||
assert.ok(!resolvedInvalid);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support relative paths)', done => {
|
||||
return service.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);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support relative paths #2)', done => {
|
||||
return service.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);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support relative paths #3)', done => {
|
||||
return service.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);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('resolveWorkspaceSync (support invalid JSON via fault tolerant parsing)', done => {
|
||||
return service.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);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('saveWorkspace (untitled)', done => {
|
||||
let savedEvent: IWorkspaceSavedEvent;
|
||||
const listener = service.onWorkspaceSaved(e => {
|
||||
savedEvent = e;
|
||||
});
|
||||
|
||||
let deletedEvent: IWorkspaceIdentifier;
|
||||
const listener2 = service.onUntitledWorkspaceDeleted(e => {
|
||||
deletedEvent = e;
|
||||
});
|
||||
|
||||
return service.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 => {
|
||||
assert.ok(savedWorkspace.id);
|
||||
assert.notEqual(savedWorkspace.id, workspace.id);
|
||||
assert.equal(savedWorkspace.configPath, workspaceConfigPath);
|
||||
|
||||
assert.equal(service.deleteWorkspaceCall, workspace);
|
||||
|
||||
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(savedWorkspace, savedEvent.workspace);
|
||||
assert.equal(workspace.configPath, savedEvent.oldConfigPath);
|
||||
|
||||
assert.deepEqual(deletedEvent, workspace);
|
||||
|
||||
listener.dispose();
|
||||
listener2.dispose();
|
||||
|
||||
extfs.delSync(workspaceConfigPath);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('saveWorkspace (saved workspace)', done => {
|
||||
return service.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 => {
|
||||
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.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
|
||||
|
||||
extfs.delSync(workspaceConfigPath);
|
||||
extfs.delSync(newWorkspaceConfigPath);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('deleteUntitledWorkspaceSync (untitled)', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
|
||||
service.deleteUntitledWorkspaceSync(workspace);
|
||||
|
||||
assert.ok(!fs.existsSync(workspace.configPath));
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('deleteUntitledWorkspaceSync (saved)', done => {
|
||||
return service.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 => {
|
||||
assert.ok(fs.existsSync(savedWorkspace.configPath));
|
||||
|
||||
service.deleteUntitledWorkspaceSync(savedWorkspace);
|
||||
|
||||
assert.ok(fs.existsSync(savedWorkspace.configPath));
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('getUntitledWorkspaceSync', done => {
|
||||
let untitled = service.getUntitledWorkspacesSync();
|
||||
assert.equal(0, untitled.length);
|
||||
|
||||
return service.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 => {
|
||||
untitled = service.getUntitledWorkspacesSync();
|
||||
|
||||
assert.equal(2, untitled.length);
|
||||
|
||||
service.deleteUntitledWorkspaceSync(untitledOne);
|
||||
service.deleteUntitledWorkspaceSync(untitledTwo);
|
||||
|
||||
untitled = service.getUntitledWorkspacesSync();
|
||||
assert.equal(0, untitled.length);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user