From 10aa7095f6fa6104155bf97adfd8e4ad6dc5eb28 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 14 Oct 2016 02:10:11 -0700 Subject: [PATCH] Disable hot exit on empty workspaces, fix uncaught exceptions --- src/vs/platform/backup/node/backupService.ts | 35 +++++++++++++++- .../workbench/electron-browser/workbench.ts | 20 +++++---- .../services/files/node/fileService.ts | 41 ++++++++++++++++--- .../textfile/browser/textFileService.ts | 3 +- 4 files changed, 82 insertions(+), 17 deletions(-) diff --git a/src/vs/platform/backup/node/backupService.ts b/src/vs/platform/backup/node/backupService.ts index 9abbb0153da89..6e355b2cdc8cc 100644 --- a/src/vs/platform/backup/node/backupService.ts +++ b/src/vs/platform/backup/node/backupService.ts @@ -32,9 +32,17 @@ export class BackupService implements IBackupService { @IWorkspaceContextService contextService?: IWorkspaceContextService ) { // IWorkspaceContextService will not exist on the main process - if (contextService) { - this.workspaceResource = contextService.getWorkspace().resource; + if (!contextService) { + return; } + + // Hot exit is disabled for empty workspaces + const workspace = contextService.getWorkspace(); + if (!workspace) { + return; + } + + this.workspaceResource = workspace.resource; } public getWorkspaceBackupPaths(): string[] { @@ -52,6 +60,10 @@ export class BackupService implements IBackupService { public pushWorkspaceBackupPaths(workspaces: string[]): void { this.load(); workspaces.forEach(workspace => { + // Hot exit is disabled for empty workspaces + if (!workspace) { + return; + } if (!this.fileContent.folderWorkspaces[workspace]) { this.fileContent.folderWorkspaces[workspace] = []; } @@ -74,6 +86,11 @@ export class BackupService implements IBackupService { } public getWorkspaceUntitledFileBackups(workspace: string): string[] { + // Hot exit is disabled for empty workspaces + if (!this.workspaceResource) { + return; + } + const workspaceHash = crypto.createHash('md5').update(this.workspaceResource.fsPath).digest('hex'); const untitledDir = path.join(this.environmentService.backupHome, workspaceHash, 'untitled'); try { @@ -87,6 +104,10 @@ export class BackupService implements IBackupService { } public getBackupResource(resource: Uri): Uri { + // Hot exit is disabled for empty workspaces + if (!this.workspaceResource) { + return; + } const workspaceHash = crypto.createHash('md5').update(this.workspaceResource.fsPath).digest('hex'); const backupName = crypto.createHash('md5').update(resource.fsPath).digest('hex'); @@ -96,6 +117,11 @@ export class BackupService implements IBackupService { } public registerResourceForBackup(resource: Uri): void { + // Hot exit is disabled for empty workspaces + if (!this.workspaceResource) { + return; + } + this.load(); if (arrays.contains(this.fileContent.folderWorkspaces[this.workspaceResource.fsPath], resource.fsPath)) { return; @@ -105,6 +131,11 @@ export class BackupService implements IBackupService { } public deregisterResourceForBackup(resource: Uri): void { + // Hot exit is disabled for empty workspaces + if (!this.workspaceResource) { + return; + } + this.load(); this.fileContent.folderWorkspaces[this.workspaceResource.fsPath] = this.fileContent.folderWorkspaces[this.workspaceResource.fsPath].filter(value => value !== resource.fsPath); this.save(); diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index d43b7bffe3ecf..0a91453ab58e5 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -172,20 +172,22 @@ export class Workbench implements IPartService { serviceCollection }; - // Restore any backups if they exist - options.filesToRestore = this.backupService.getWorkspaceTextFilesWithBackups(workspace.resource.fsPath).map(filePath => { - return { resource: Uri.file(filePath), options: { pinned: true } }; - }); - options.untitledFilesToRestore = this.backupService.getWorkspaceUntitledFileBackups(workspace.resource.fsPath).map(untitledFilePath => { - return { resource: Uri.file(untitledFilePath), options: { pinned: true } }; - }); + // Restore any backups if they exist for this workspace (empty workspaces are not supported yet) + if (workspace) { + options.filesToRestore = this.backupService.getWorkspaceTextFilesWithBackups(workspace.resource.fsPath).map(filePath => { + return { resource: Uri.file(filePath), options: { pinned: true } }; + }); + options.untitledFilesToRestore = this.backupService.getWorkspaceUntitledFileBackups(workspace.resource.fsPath).map(untitledFilePath => { + return { resource: Uri.file(untitledFilePath), options: { pinned: true } }; + }); + } this.hasFilesToCreateOpenOrDiff = (options.filesToCreate && options.filesToCreate.length > 0) || (options.filesToOpen && options.filesToOpen.length > 0) || (options.filesToDiff && options.filesToDiff.length > 0) || - (options.filesToRestore.length > 0) || - (options.untitledFilesToRestore.length > 0); + (options.filesToRestore && options.filesToRestore.length > 0) || + (options.untitledFilesToRestore && options.untitledFilesToRestore.length > 0); this.toDispose = []; this.toShutdown = []; diff --git a/src/vs/workbench/services/files/node/fileService.ts b/src/vs/workbench/services/files/node/fileService.ts index 9c4d289cd1b23..f3e1da90faaf1 100644 --- a/src/vs/workbench/services/files/node/fileService.ts +++ b/src/vs/workbench/services/files/node/fileService.ts @@ -463,17 +463,36 @@ export class FileService implements IFileService { this.backupService.registerResourceForBackup(resource); } const backupResource = this.getBackupPath(resource); + + // Hot exit is disabled for empty workspaces + if (!backupResource) { + return TPromise.as(null); + } + console.log(`Backing up to ${backupResource.fsPath}`); return this.updateContent(backupResource, content); } public discardBackup(resource: uri): TPromise { this.backupService.deregisterResourceForBackup(resource); - return this.del(this.getBackupPath(resource)); + const backupResource = this.getBackupPath(resource); + + // Hot exit is disabled for empty workspaces + if (!backupResource) { + return TPromise.as(null); + } + + return this.del(backupResource); } public discardBackups(): TPromise { - return this.del(uri.file(this.getBackupRoot())); + // Hot exit is disabled for empty workspaces + const backupRootPath = this.getBackupRootPath(); + if (!backupRootPath) { + return TPromise.as(void 0); + } + + return this.del(uri.file(backupRootPath)); } public isHotExitEnabled(): boolean { @@ -483,13 +502,25 @@ export class FileService implements IFileService { // Helpers private getBackupPath(resource: uri): uri { + // Hot exit is disabled for empty workspaces + const backupRootPath = this.getBackupRootPath(); + if (!backupRootPath) { + return null; + } + const backupName = crypto.createHash('md5').update(resource.fsPath).digest('hex'); - const backupPath = paths.join(this.getBackupRoot(), resource.scheme, backupName); + const backupPath = paths.join(backupRootPath, resource.scheme, backupName); return uri.file(backupPath); } - private getBackupRoot(): string { - let workspaceHash = crypto.createHash('md5').update(this.contextService.getWorkspace().resource.fsPath).digest('hex'); + private getBackupRootPath(): string { + // Hot exit is disabled for empty workspaces + const workspace = this.contextService.getWorkspace(); + if (!workspace) { + return null; + } + + const workspaceHash = crypto.createHash('md5').update(workspace.resource.fsPath).digest('hex'); return paths.join(this.environmentService.userDataPath, 'Backups', workspaceHash); } diff --git a/src/vs/workbench/services/textfile/browser/textFileService.ts b/src/vs/workbench/services/textfile/browser/textFileService.ts index f0d236260786d..d10171202ac56 100644 --- a/src/vs/workbench/services/textfile/browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/browser/textFileService.ts @@ -231,7 +231,8 @@ export abstract class TextFileService implements ITextFileService { this.saveAll().done(null, errors.onUnexpectedError); } - this.configuredHotExit = configuration && configuration.files && configuration.files.hotExit; + // Hot exit is disabled for empty workspaces + this.configuredHotExit = this.contextService.getWorkspace() && configuration && configuration.files && configuration.files.hotExit; // Check for change in files associations const filesAssociation = configuration && configuration.files && configuration.files.associations;