backupFileService.ts 3.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

import * as path from 'path';
import * as crypto from 'crypto';
import pfs = require('vs/base/node/pfs');
import Uri from 'vs/base/common/uri';
12
import { IBackupWorkspacesFormat } from 'vs/platform/backup/common/backup';
13 14 15 16 17 18 19 20 21 22
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IFileService } from 'vs/platform/files/common/files';
import { TPromise } from 'vs/base/common/winjs.base';

export class BackupFileService implements IBackupFileService {

	public _serviceBrand: any;

	protected backupHome: string;
D
Daniel Imms 已提交
23
	protected workspacesJsonPath: string;
24 25 26 27 28 29 30

	constructor(
		private currentWorkspace: Uri,
		@IEnvironmentService environmentService: IEnvironmentService,
		@IFileService private fileService: IFileService
	) {
		this.backupHome = environmentService.backupHome;
D
Daniel Imms 已提交
31 32 33
		this.workspacesJsonPath = environmentService.backupWorkspacesPath;
	}

34
	public getWorkspaceBackupPaths(): TPromise<string[]> {
35 36
		return this.loadWorkspaces().then(workspacesJsonContent => {
			return workspacesJsonContent.folderWorkspaces;
37 38 39
		});
	}

40
	public hasBackup(resource: Uri): TPromise<boolean> {
41 42 43 44
		const backupResource = this.getBackupResource(resource);
		if (!backupResource) {
			return TPromise.as(false);
		}
45
		return pfs.exists(backupResource.fsPath);
46 47 48 49 50 51 52 53
	}

	public getBackupResource(resource: Uri): Uri {
		// Hot exit is disabled for empty workspaces
		if (!this.currentWorkspace) {
			return null;
		}

54 55
		// Only hash the file path if the file is not untitled
		const backupName = resource.scheme === 'untitled' ? resource.fsPath : crypto.createHash('md5').update(resource.fsPath).digest('hex');
56 57 58 59 60 61 62 63 64
		const backupPath = path.join(this.getWorkspaceBackupDirectory(), resource.scheme, backupName);
		return Uri.file(backupPath);
	}

	private getWorkspaceBackupDirectory(): string {
		const workspaceHash = crypto.createHash('md5').update(this.currentWorkspace.fsPath).digest('hex');
		return path.join(this.backupHome, workspaceHash);
	}

65 66
	public backupResource(resource: Uri, content: string): TPromise<void> {
		const backupResource = this.getBackupResource(resource);
67

68 69 70 71
		// Hot exit is disabled for empty workspaces
		if (!backupResource) {
			return TPromise.as(void 0);
		}
72

73
		return this.fileService.updateContent(backupResource, content).then(() => void 0);
74 75
	}

76 77
	public discardResourceBackup(resource: Uri): TPromise<void> {
		const backupResource = this.getBackupResource(resource);
78

79 80 81 82
		// Hot exit is disabled for empty workspaces
		if (!backupResource) {
			return TPromise.as(void 0);
		}
83

84
		return this.fileService.del(backupResource);
85 86
	}

87
	public discardAllWorkspaceBackups(): TPromise<void> {
88 89 90
		return this.fileService.del(Uri.file(this.getWorkspaceBackupDirectory()));
	}

91
	private loadWorkspaces(): TPromise<IBackupWorkspacesFormat> {
D
Daniel Imms 已提交
92 93
		return pfs.fileExists(this.workspacesJsonPath).then(exists => {
			if (!exists) {
94
				return { folderWorkspaces: [] };
D
Daniel Imms 已提交
95 96 97 98 99 100 101 102 103
			}

			return pfs.readFile(this.workspacesJsonPath, 'utf8').then(content => {
				try {
					return JSON.parse(content.toString());
				} catch (ex) {
					return [];
				}
			}).then(content => {
104 105 106
				let result = content;
				if (!result.folderWorkspaces) {
					result.folderWorkspaces = [];
D
Daniel Imms 已提交
107
				}
108
				return result;
D
Daniel Imms 已提交
109 110 111
			});
		});
	}
112
}