提交 8667e717 编写于 作者: S Sandeep Somavarapu

#109019 remove dependency on backup location

上级 6479a9c4
...@@ -234,7 +234,7 @@ class DesktopMain extends Disposable { ...@@ -234,7 +234,7 @@ class DesktopMain extends Disposable {
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
// User Data Provider // User Data Provider
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(this.environmentService.appSettingsHome, this.configuration.backupPath ? URI.file(this.configuration.backupPath) : undefined, diskFileSystemProvider, this.environmentService, logService)); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, logService));
// Uri Identity // Uri Identity
const uriIdentityService = new UriIdentityService(fileService); const uriIdentityService = new UriIdentityService(fileService);
......
...@@ -207,7 +207,7 @@ class DesktopMain extends Disposable { ...@@ -207,7 +207,7 @@ class DesktopMain extends Disposable {
fileService.registerProvider(Schemas.file, simpleFileSystemProvider); fileService.registerProvider(Schemas.file, simpleFileSystemProvider);
// User Data Provider // User Data Provider
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(URI.file('user-home'), undefined, simpleFileSystemProvider, this.environmentService, logService)); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, simpleFileSystemProvider, Schemas.userData, logService));
// Uri Identity // Uri Identity
const uriIdentityService = new UriIdentityService(fileService); const uriIdentityService = new UriIdentityService(fileService);
......
...@@ -67,7 +67,7 @@ export class NodeTestBackupFileService extends BackupFileService { ...@@ -67,7 +67,7 @@ export class NodeTestBackupFileService extends BackupFileService {
const fileService = new FileService(logService); const fileService = new FileService(logService);
const diskFileSystemProvider = new DiskFileSystemProvider(logService); const diskFileSystemProvider = new DiskFileSystemProvider(logService);
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, URI.file(workspaceBackupPath), diskFileSystemProvider, environmentService, logService)); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, logService));
super(environmentService, fileService, logService); super(environmentService, fileService, logService);
......
...@@ -7,7 +7,7 @@ import { URI } from 'vs/base/common/uri'; ...@@ -7,7 +7,7 @@ import { URI } from 'vs/base/common/uri';
import * as resources from 'vs/base/common/resources'; import * as resources from 'vs/base/common/resources';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import * as errors from 'vs/base/common/errors'; import * as errors from 'vs/base/common/errors';
import { Disposable, IDisposable, dispose, toDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { Disposable, IDisposable, dispose, toDisposable, MutableDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { RunOnceScheduler } from 'vs/base/common/async'; import { RunOnceScheduler } from 'vs/base/common/async';
import { FileChangeType, FileChangesEvent, IFileService, whenProviderRegistered, FileOperationError, FileOperationResult } from 'vs/platform/files/common/files'; import { FileChangeType, FileChangesEvent, IFileService, whenProviderRegistered, FileOperationError, FileOperationResult } from 'vs/platform/files/common/files';
import { ConfigurationModel, ConfigurationModelParser, UserSettings } from 'vs/platform/configuration/common/configurationModels'; import { ConfigurationModel, ConfigurationModelParser, UserSettings } from 'vs/platform/configuration/common/configurationModels';
...@@ -92,6 +92,7 @@ class FileServiceBasedConfiguration extends Disposable { ...@@ -92,6 +92,7 @@ class FileServiceBasedConfiguration extends Disposable {
) { ) {
super(); super();
this.allResources = [...this.settingsResources, ...this.standAloneConfigurationResources.map(([, resource]) => resource)]; this.allResources = [...this.settingsResources, ...this.standAloneConfigurationResources.map(([, resource]) => resource)];
this._register(combinedDisposable(...this.allResources.map(resource => this.fileService.watch(resources.dirname(resource)))));
this._folderSettingsModelParser = new ConfigurationModelParser(name, this.scopes); this._folderSettingsModelParser = new ConfigurationModelParser(name, this.scopes);
this._standAloneConfigurations = []; this._standAloneConfigurations = [];
this._cache = new ConfigurationModel(); this._cache = new ConfigurationModel();
......
...@@ -111,7 +111,7 @@ suite('ConfigurationEditingService', () => { ...@@ -111,7 +111,7 @@ suite('ConfigurationEditingService', () => {
const fileService = new FileService(new NullLogService()); const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, undefined, diskFileSystemProvider, environmentService, new NullLogService())); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, new NullLogService()));
instantiationService.stub(IFileService, fileService); instantiationService.stub(IFileService, fileService);
instantiationService.stub(IRemoteAgentService, remoteAgentService); instantiationService.stub(IRemoteAgentService, remoteAgentService);
const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService()); const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService());
......
...@@ -116,7 +116,7 @@ suite('WorkspaceContextService - Folder', () => { ...@@ -116,7 +116,7 @@ suite('WorkspaceContextService - Folder', () => {
const fileService = new FileService(new NullLogService()); const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, undefined, new DiskFileSystemProvider(new NullLogService()), environmentService, new NullLogService())); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService()), Schemas.userData, new NullLogService()));
workspaceContextService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, new RemoteAgentService(environmentService, { _serviceBrand: undefined, ...product }, new RemoteAuthorityResolverService(), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService()); workspaceContextService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, new RemoteAgentService(environmentService, { _serviceBrand: undefined, ...product }, new RemoteAuthorityResolverService(), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService());
return (<WorkspaceService>workspaceContextService).initialize(convertToWorkspacePayload(URI.file(folderDir))); return (<WorkspaceService>workspaceContextService).initialize(convertToWorkspacePayload(URI.file(folderDir)));
}); });
...@@ -182,7 +182,7 @@ suite('WorkspaceContextService - Workspace', () => { ...@@ -182,7 +182,7 @@ suite('WorkspaceContextService - Workspace', () => {
const fileService = new FileService(new NullLogService()); const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, undefined, diskFileSystemProvider, environmentService, new NullLogService())); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, new NullLogService()));
const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService()); const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService());
instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IWorkspaceContextService, workspaceService);
...@@ -242,7 +242,7 @@ suite('WorkspaceContextService - Workspace Editing', () => { ...@@ -242,7 +242,7 @@ suite('WorkspaceContextService - Workspace Editing', () => {
const fileService = new FileService(new NullLogService()); const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, undefined, diskFileSystemProvider, environmentService, new NullLogService())); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, new NullLogService()));
const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService()); const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService());
instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IWorkspaceContextService, workspaceService);
...@@ -503,7 +503,7 @@ suite('WorkspaceService - Initialization', () => { ...@@ -503,7 +503,7 @@ suite('WorkspaceService - Initialization', () => {
const fileService = new FileService(new NullLogService()); const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, undefined, diskFileSystemProvider, environmentService, new NullLogService())); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, new NullLogService()));
const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService()); const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService());
instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IWorkspaceContextService, workspaceService);
instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService);
...@@ -780,7 +780,7 @@ suite('WorkspaceConfigurationService - Folder', () => { ...@@ -780,7 +780,7 @@ suite('WorkspaceConfigurationService - Folder', () => {
fileService = new FileService(new NullLogService()); fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, undefined, diskFileSystemProvider, environmentService, new NullLogService())); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, new NullLogService()));
workspaceService = disposableStore.add(new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService())); workspaceService = disposableStore.add(new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService()));
instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IWorkspaceContextService, workspaceService);
instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService);
...@@ -1286,7 +1286,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => { ...@@ -1286,7 +1286,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => {
const fileService = new FileService(new NullLogService()); const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, undefined, diskFileSystemProvider, environmentService, new NullLogService())); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, new NullLogService()));
const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService()); const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService());
instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IWorkspaceContextService, workspaceService);
...@@ -1889,7 +1889,7 @@ suite('WorkspaceConfigurationService - Remote Folder', () => { ...@@ -1889,7 +1889,7 @@ suite('WorkspaceConfigurationService - Remote Folder', () => {
const remoteAgentService = instantiationService.stub(IRemoteAgentService, <Partial<IRemoteAgentService>>{ getEnvironment: () => remoteEnvironmentPromise }); const remoteAgentService = instantiationService.stub(IRemoteAgentService, <Partial<IRemoteAgentService>>{ getEnvironment: () => remoteEnvironmentPromise });
const fileService = new FileService(new NullLogService()); const fileService = new FileService(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, undefined, diskFileSystemProvider, environmentService, new NullLogService())); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, new NullLogService()));
const configurationCache: IConfigurationCache = { read: () => Promise.resolve(''), write: () => Promise.resolve(), remove: () => Promise.resolve(), needsCaching: () => false }; const configurationCache: IConfigurationCache = { read: () => Promise.resolve(''), write: () => Promise.resolve(), remove: () => Promise.resolve(), needsCaching: () => false };
testObject = new WorkspaceService({ configurationCache, remoteAuthority }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService()); testObject = new WorkspaceService({ configurationCache, remoteAuthority }, environmentService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService());
instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IWorkspaceContextService, testObject);
......
...@@ -49,6 +49,7 @@ import { flatten } from 'vs/base/common/arrays'; ...@@ -49,6 +49,7 @@ import { flatten } from 'vs/base/common/arrays';
import { BrowserFeatures, KeyboardSupport } from 'vs/base/browser/canIUse'; import { BrowserFeatures, KeyboardSupport } from 'vs/base/browser/canIUse';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { dirname } from 'vs/base/common/resources';
interface ContributedKeyBinding { interface ContributedKeyBinding {
command: string; command: string;
...@@ -658,6 +659,7 @@ class UserKeybindings extends Disposable { ...@@ -658,6 +659,7 @@ class UserKeybindings extends Disposable {
) { ) {
super(); super();
this._register(fileService.watch(dirname(keybindingsResource)));
this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(changed => { this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(changed => {
if (changed) { if (changed) {
this._onDidChange.fire(); this._onDidChange.fire();
......
...@@ -117,7 +117,7 @@ suite('KeybindingsEditing', () => { ...@@ -117,7 +117,7 @@ suite('KeybindingsEditing', () => {
const fileService = new FileService(new NullLogService()); const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, undefined, diskFileSystemProvider, environmentService, new NullLogService())); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, new NullLogService()));
instantiationService.stub(IFileService, fileService); instantiationService.stub(IFileService, fileService);
instantiationService.stub(IUriIdentityService, new UriIdentityService(fileService)); instantiationService.stub(IUriIdentityService, new UriIdentityService(fileService));
instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService()); instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService());
......
...@@ -4,14 +4,14 @@ ...@@ -4,14 +4,14 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { IFileSystemProviderWithFileReadWriteCapability, IFileChange, IWatchOptions, IStat, FileOverwriteOptions, FileType, FileWriteOptions, FileDeleteOptions, FileSystemProviderCapabilities, IFileSystemProviderWithOpenReadWriteCloseCapability, FileOpenOptions, hasReadWriteCapability, hasOpenReadWriteCloseCapability, IFileSystemProviderWithFileReadStreamCapability, FileReadStreamOptions, hasFileReadStreamCapability } from 'vs/platform/files/common/files'; import { IFileSystemProviderWithFileReadWriteCapability, IFileChange, IWatchOptions, IStat, FileOverwriteOptions, FileType, FileWriteOptions, FileDeleteOptions, FileSystemProviderCapabilities, IFileSystemProviderWithOpenReadWriteCloseCapability, FileOpenOptions, hasReadWriteCapability, hasOpenReadWriteCloseCapability, IFileSystemProviderWithFileReadStreamCapability, FileReadStreamOptions, hasFileReadStreamCapability } from 'vs/platform/files/common/files';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { CancellationToken } from 'vs/base/common/cancellation'; import { CancellationToken } from 'vs/base/common/cancellation';
import { ReadableStreamEvents } from 'vs/base/common/stream'; import { ReadableStreamEvents } from 'vs/base/common/stream';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
import { ExtUri, extUri, extUriIgnorePathCase } from 'vs/base/common/resources'; import { ExtUri, extUri, extUriIgnorePathCase } from 'vs/base/common/resources';
import { TernarySearchTree } from 'vs/base/common/map';
export class FileUserDataProvider extends Disposable implements export class FileUserDataProvider extends Disposable implements
IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithFileReadWriteCapability,
...@@ -24,38 +24,32 @@ export class FileUserDataProvider extends Disposable implements ...@@ -24,38 +24,32 @@ export class FileUserDataProvider extends Disposable implements
private readonly _onDidChangeFile = this._register(new Emitter<readonly IFileChange[]>()); private readonly _onDidChangeFile = this._register(new Emitter<readonly IFileChange[]>());
readonly onDidChangeFile: Event<readonly IFileChange[]> = this._onDidChangeFile.event; readonly onDidChangeFile: Event<readonly IFileChange[]> = this._onDidChangeFile.event;
private readonly userDataHome: URI;
private readonly backupHome: URI | undefined;
private extUri: ExtUri; private extUri: ExtUri;
private readonly watchResources = TernarySearchTree.forUris<URI>(uri => this.extUri.ignorePathCasing(uri));
constructor( constructor(
/* private readonly fileSystemScheme: string,
Original userdata and backup home locations. Used to
- listen to changes and trigger change events
- Compute UserData URIs from original URIs and vice-versa
*/
private readonly fileSystemUserDataHome: URI,
public fileSystemBackupsHome: URI | undefined,
private readonly fileSystemProvider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability, private readonly fileSystemProvider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability,
environmentService: IWorkbenchEnvironmentService, private readonly userDataScheme: string,
private readonly logService: ILogService, private readonly logService: ILogService,
) { ) {
super(); super();
this.userDataHome = environmentService.userRoamingDataHome;
this.backupHome = environmentService.backupWorkspaceHome;
this.extUri = !!(this.capabilities & FileSystemProviderCapabilities.PathCaseSensitive) ? extUri : extUriIgnorePathCase; this.extUri = !!(this.capabilities & FileSystemProviderCapabilities.PathCaseSensitive) ? extUri : extUriIgnorePathCase;
// update extUri as capabilites might change. // update extUri as capabilites might change.
this._register(this.onDidChangeCapabilities(() => this.extUri = !!(this.capabilities & FileSystemProviderCapabilities.PathCaseSensitive) ? extUri : extUriIgnorePathCase)); this._register(this.onDidChangeCapabilities(() => this.extUri = !!(this.capabilities & FileSystemProviderCapabilities.PathCaseSensitive) ? extUri : extUriIgnorePathCase));
// Assumption: This path always exists
this._register(this.fileSystemProvider.watch(this.fileSystemUserDataHome, { recursive: false, excludes: [] }));
this._register(this.fileSystemProvider.onDidChangeFile(e => this.handleFileChanges(e))); this._register(this.fileSystemProvider.onDidChangeFile(e => this.handleFileChanges(e)));
} }
watch(resource: URI, opts: IWatchOptions): IDisposable { watch(resource: URI, opts: IWatchOptions): IDisposable {
return this.fileSystemProvider.watch(this.toFileSystemResource(resource), opts); this.watchResources.set(resource, resource);
const disposable = this.fileSystemProvider.watch(this.toFileSystemResource(resource), opts);
return toDisposable(() => {
this.watchResources.delete(resource);
disposable.dispose();
});
} }
stat(resource: URI): Promise<IStat> { stat(resource: URI): Promise<IStat> {
...@@ -131,7 +125,7 @@ export class FileUserDataProvider extends Disposable implements ...@@ -131,7 +125,7 @@ export class FileUserDataProvider extends Disposable implements
const userDataChanges: IFileChange[] = []; const userDataChanges: IFileChange[] = [];
for (const change of changes) { for (const change of changes) {
const userDataResource = this.toUserDataResource(change.resource); const userDataResource = this.toUserDataResource(change.resource);
if (userDataResource) { if (this.watchResources.findSubstr(userDataResource)) {
userDataChanges.push({ userDataChanges.push({
resource: userDataResource, resource: userDataResource,
type: change.type type: change.type
...@@ -145,26 +139,11 @@ export class FileUserDataProvider extends Disposable implements ...@@ -145,26 +139,11 @@ export class FileUserDataProvider extends Disposable implements
} }
private toFileSystemResource(userDataResource: URI): URI { private toFileSystemResource(userDataResource: URI): URI {
// Backup Resource return userDataResource.with({ scheme: this.fileSystemScheme });
if (this.backupHome && this.fileSystemBackupsHome && this.extUri.isEqualOrParent(userDataResource, this.backupHome)) {
const relativePath = this.extUri.relativePath(this.backupHome, userDataResource);
return relativePath ? this.extUri.joinPath(this.fileSystemBackupsHome, relativePath) : this.fileSystemBackupsHome;
}
const relativePath = this.extUri.relativePath(this.userDataHome, userDataResource)!;
return this.extUri.joinPath(this.fileSystemUserDataHome, relativePath);
} }
private toUserDataResource(fileSystemResource: URI): URI | null { private toUserDataResource(fileSystemResource: URI): URI {
if (this.extUri.isEqualOrParent(fileSystemResource, this.fileSystemUserDataHome)) { return fileSystemResource.with({ scheme: this.userDataScheme });
const relativePath = this.extUri.relativePath(this.fileSystemUserDataHome, fileSystemResource);
return relativePath ? this.extUri.joinPath(this.userDataHome, relativePath) : this.userDataHome;
}
if (this.backupHome && this.fileSystemBackupsHome && this.extUri.isEqualOrParent(fileSystemResource, this.fileSystemBackupsHome)) {
const relativePath = this.extUri.relativePath(this.fileSystemBackupsHome, fileSystemResource);
return relativePath ? this.extUri.joinPath(this.backupHome, relativePath) : this.backupHome;
}
return null;
} }
} }
...@@ -13,15 +13,15 @@ import { NullLogService } from 'vs/platform/log/common/log'; ...@@ -13,15 +13,15 @@ import { NullLogService } from 'vs/platform/log/common/log';
import { Schemas } from 'vs/base/common/network'; import { Schemas } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider';
import { joinPath, dirname } from 'vs/base/common/resources'; import { dirname, isEqual, joinPath } from 'vs/base/common/resources';
import { VSBuffer } from 'vs/base/common/buffer'; import { VSBuffer } from 'vs/base/common/buffer';
import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider';
import { DisposableStore, IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { DisposableStore, IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { BrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
import { Emitter, Event } from 'vs/base/common/event'; import { Emitter, Event } from 'vs/base/common/event';
import { timeout } from 'vs/base/common/async';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { TestProductService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestProductService } from 'vs/workbench/test/browser/workbenchTestServices';
import { NativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService';
import { TestWorkbenchConfiguration } from 'vs/workbench/test/electron-browser/workbenchTestServices';
suite('FileUserDataProvider', () => { suite('FileUserDataProvider', () => {
...@@ -43,15 +43,15 @@ suite('FileUserDataProvider', () => { ...@@ -43,15 +43,15 @@ suite('FileUserDataProvider', () => {
disposables.add(testObject.registerProvider(Schemas.file, diskFileSystemProvider)); disposables.add(testObject.registerProvider(Schemas.file, diskFileSystemProvider));
const workspaceId = 'workspaceId'; const workspaceId = 'workspaceId';
environmentService = new BrowserWorkbenchEnvironmentService({ remoteAuthority: 'remote', workspaceId, logsPath: URI.file('logFile') }, TestProductService);
rootResource = URI.file(path.join(os.tmpdir(), 'vsctests', uuid.generateUuid())); rootResource = URI.file(path.join(os.tmpdir(), 'vsctests', uuid.generateUuid()));
userDataHomeOnDisk = joinPath(rootResource, 'user'); userDataHomeOnDisk = joinPath(rootResource, 'user');
const backupHome = joinPath(rootResource, 'Backups'); const backupHome = joinPath(rootResource, 'Backups');
backupWorkspaceHomeOnDisk = joinPath(backupHome, workspaceId); backupWorkspaceHomeOnDisk = joinPath(backupHome, workspaceId);
await Promise.all([testObject.createFolder(userDataHomeOnDisk), testObject.createFolder(backupWorkspaceHomeOnDisk)]); await Promise.all([testObject.createFolder(userDataHomeOnDisk), testObject.createFolder(backupWorkspaceHomeOnDisk)]);
fileUserDataProvider = new FileUserDataProvider(userDataHomeOnDisk, backupWorkspaceHomeOnDisk, diskFileSystemProvider, environmentService, logService); environmentService = new NativeWorkbenchEnvironmentService({ ...TestWorkbenchConfiguration, 'user-data-dir': rootResource.fsPath, backupPath: backupWorkspaceHomeOnDisk.fsPath }, TestProductService);
fileUserDataProvider = new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, logService);
disposables.add(fileUserDataProvider); disposables.add(fileUserDataProvider);
disposables.add(testObject.registerProvider(Schemas.userData, fileUserDataProvider)); disposables.add(testObject.registerProvider(Schemas.userData, fileUserDataProvider));
}); });
...@@ -305,41 +305,29 @@ class TestFileSystemProvider implements IFileSystemProviderWithFileReadWriteCapa ...@@ -305,41 +305,29 @@ class TestFileSystemProvider implements IFileSystemProviderWithFileReadWriteCapa
suite('FileUserDataProvider - Watching', () => { suite('FileUserDataProvider - Watching', () => {
let testObject: IFileService; let testObject: FileUserDataProvider;
let localBackupsResource: URI;
let localUserDataResource: URI;
let environmentService: IWorkbenchEnvironmentService;
const disposables = new DisposableStore(); const disposables = new DisposableStore();
const rootFileResource = URI.file(path.join(os.tmpdir(), 'vsctests', uuid.generateUuid()));
const rootUserDataResource = rootFileResource.with({ scheme: Schemas.userData });
const fileEventEmitter: Emitter<readonly IFileChange[]> = new Emitter<readonly IFileChange[]>(); const fileEventEmitter: Emitter<readonly IFileChange[]> = new Emitter<readonly IFileChange[]>();
disposables.add(fileEventEmitter); disposables.add(fileEventEmitter);
setup(() => { setup(() => {
testObject = disposables.add(new FileUserDataProvider(Schemas.file, new TestFileSystemProvider(fileEventEmitter.event), Schemas.userData, new NullLogService()));
environmentService = new BrowserWorkbenchEnvironmentService({ remoteAuthority: 'remote', workspaceId: 'workspaceId', logsPath: URI.file('logFile') }, TestProductService);
const rootResource = URI.file(path.join(os.tmpdir(), 'vsctests', uuid.generateUuid()));
localUserDataResource = joinPath(rootResource, 'user');
localBackupsResource = joinPath(rootResource, 'Backups');
const userDataFileSystemProvider = new FileUserDataProvider(localUserDataResource, localBackupsResource, new TestFileSystemProvider(fileEventEmitter.event), environmentService, new NullLogService());
disposables.add(userDataFileSystemProvider);
testObject = new FileService(new NullLogService());
disposables.add(testObject);
disposables.add(testObject.registerProvider(Schemas.userData, userDataFileSystemProvider));
}); });
teardown(() => disposables.clear()); teardown(() => disposables.clear());
test('file added change event', done => { test('file added change event', done => {
const expected = environmentService.settingsResource; disposables.add(testObject.watch(rootUserDataResource, { excludes: [], recursive: false }));
const target = joinPath(localUserDataResource, 'settings.json'); const expected = joinPath(rootUserDataResource, 'settings.json');
testObject.onDidFilesChange(e => { const target = joinPath(rootFileResource, 'settings.json');
if (e.contains(expected, FileChangeType.ADDED)) { disposables.add(testObject.onDidChangeFile(e => {
if (isEqual(e[0].resource, expected) && e[0].type === FileChangeType.ADDED) {
done(); done();
} }
}); }));
fileEventEmitter.fire([{ fileEventEmitter.fire([{
resource: target, resource: target,
type: FileChangeType.ADDED type: FileChangeType.ADDED
...@@ -347,13 +335,14 @@ suite('FileUserDataProvider - Watching', () => { ...@@ -347,13 +335,14 @@ suite('FileUserDataProvider - Watching', () => {
}); });
test('file updated change event', done => { test('file updated change event', done => {
const expected = environmentService.settingsResource; disposables.add(testObject.watch(rootUserDataResource, { excludes: [], recursive: false }));
const target = joinPath(localUserDataResource, 'settings.json'); const expected = joinPath(rootUserDataResource, 'settings.json');
testObject.onDidFilesChange(e => { const target = joinPath(rootFileResource, 'settings.json');
if (e.contains(expected, FileChangeType.UPDATED)) { disposables.add(testObject.onDidChangeFile(e => {
if (isEqual(e[0].resource, expected) && e[0].type === FileChangeType.UPDATED) {
done(); done();
} }
}); }));
fileEventEmitter.fire([{ fileEventEmitter.fire([{
resource: target, resource: target,
type: FileChangeType.UPDATED type: FileChangeType.UPDATED
...@@ -361,13 +350,14 @@ suite('FileUserDataProvider - Watching', () => { ...@@ -361,13 +350,14 @@ suite('FileUserDataProvider - Watching', () => {
}); });
test('file deleted change event', done => { test('file deleted change event', done => {
const expected = environmentService.settingsResource; disposables.add(testObject.watch(rootUserDataResource, { excludes: [], recursive: false }));
const target = joinPath(localUserDataResource, 'settings.json'); const expected = joinPath(rootUserDataResource, 'settings.json');
testObject.onDidFilesChange(e => { const target = joinPath(rootFileResource, 'settings.json');
if (e.contains(expected, FileChangeType.DELETED)) { disposables.add(testObject.onDidChangeFile(e => {
if (isEqual(e[0].resource, expected) && e[0].type === FileChangeType.DELETED) {
done(); done();
} }
}); }));
fileEventEmitter.fire([{ fileEventEmitter.fire([{
resource: target, resource: target,
type: FileChangeType.DELETED type: FileChangeType.DELETED
...@@ -375,13 +365,14 @@ suite('FileUserDataProvider - Watching', () => { ...@@ -375,13 +365,14 @@ suite('FileUserDataProvider - Watching', () => {
}); });
test('file under folder created change event', done => { test('file under folder created change event', done => {
const expected = joinPath(environmentService.snippetsHome, 'settings.json'); disposables.add(testObject.watch(rootUserDataResource, { excludes: [], recursive: false }));
const target = joinPath(localUserDataResource, 'snippets', 'settings.json'); const expected = joinPath(rootUserDataResource, 'snippets', 'settings.json');
testObject.onDidFilesChange(e => { const target = joinPath(rootFileResource, 'snippets', 'settings.json');
if (e.contains(expected, FileChangeType.ADDED)) { disposables.add(testObject.onDidChangeFile(e => {
if (isEqual(e[0].resource, expected) && e[0].type === FileChangeType.ADDED) {
done(); done();
} }
}); }));
fileEventEmitter.fire([{ fileEventEmitter.fire([{
resource: target, resource: target,
type: FileChangeType.ADDED type: FileChangeType.ADDED
...@@ -389,13 +380,14 @@ suite('FileUserDataProvider - Watching', () => { ...@@ -389,13 +380,14 @@ suite('FileUserDataProvider - Watching', () => {
}); });
test('file under folder updated change event', done => { test('file under folder updated change event', done => {
const expected = joinPath(environmentService.snippetsHome, 'settings.json'); disposables.add(testObject.watch(rootUserDataResource, { excludes: [], recursive: false }));
const target = joinPath(localUserDataResource, 'snippets', 'settings.json'); const expected = joinPath(rootUserDataResource, 'snippets', 'settings.json');
testObject.onDidFilesChange(e => { const target = joinPath(rootFileResource, 'snippets', 'settings.json');
if (e.contains(expected, FileChangeType.UPDATED)) { disposables.add(testObject.onDidChangeFile(e => {
if (isEqual(e[0].resource, expected) && e[0].type === FileChangeType.UPDATED) {
done(); done();
} }
}); }));
fileEventEmitter.fire([{ fileEventEmitter.fire([{
resource: target, resource: target,
type: FileChangeType.UPDATED type: FileChangeType.UPDATED
...@@ -403,72 +395,45 @@ suite('FileUserDataProvider - Watching', () => { ...@@ -403,72 +395,45 @@ suite('FileUserDataProvider - Watching', () => {
}); });
test('file under folder deleted change event', done => { test('file under folder deleted change event', done => {
const expected = joinPath(environmentService.snippetsHome, 'settings.json'); disposables.add(testObject.watch(rootUserDataResource, { excludes: [], recursive: false }));
const target = joinPath(localUserDataResource, 'snippets', 'settings.json'); const expected = joinPath(rootUserDataResource, 'snippets', 'settings.json');
testObject.onDidFilesChange(e => { const target = joinPath(rootFileResource, 'snippets', 'settings.json');
if (e.contains(expected, FileChangeType.DELETED)) { disposables.add(testObject.onDidChangeFile(e => {
if (isEqual(e[0].resource, expected) && e[0].type === FileChangeType.DELETED) {
done(); done();
} }
}); }));
fileEventEmitter.fire([{ fileEventEmitter.fire([{
resource: target, resource: target,
type: FileChangeType.DELETED type: FileChangeType.DELETED
}]); }]);
}); });
test('event is not triggered if file is not under user data', async () => { test('event is not triggered if not watched', async () => {
const target = joinPath(dirname(localUserDataResource), 'settings.json'); const target = joinPath(rootFileResource, 'settings.json');
let triggered = false; let triggered = false;
testObject.onDidFilesChange(() => triggered = true); testObject.onDidChangeFile(() => triggered = true);
fileEventEmitter.fire([{ fileEventEmitter.fire([{
resource: target, resource: target,
type: FileChangeType.DELETED type: FileChangeType.DELETED
}]); }]);
await timeout(0);
if (triggered) { if (triggered) {
assert.fail('event should not be triggered'); assert.fail('event should not be triggered');
} }
}); });
test('backup file created change event', done => { test('event is not triggered if not watched 2', async () => {
const expected = joinPath(environmentService.backupWorkspaceHome!, 'settings.json'); disposables.add(testObject.watch(rootUserDataResource, { excludes: [], recursive: false }));
const target = joinPath(localBackupsResource, 'settings.json'); const target = joinPath(dirname(rootFileResource), 'settings.json');
testObject.onDidFilesChange(e => { let triggered = false;
if (e.contains(expected, FileChangeType.ADDED)) { testObject.onDidChangeFile(() => triggered = true);
done();
}
});
fileEventEmitter.fire([{
resource: target,
type: FileChangeType.ADDED
}]);
});
test('backup file update change event', done => {
const expected = joinPath(environmentService.backupWorkspaceHome!, 'settings.json');
const target = joinPath(localBackupsResource, 'settings.json');
testObject.onDidFilesChange(e => {
if (e.contains(expected, FileChangeType.UPDATED)) {
done();
}
});
fileEventEmitter.fire([{
resource: target,
type: FileChangeType.UPDATED
}]);
});
test('backup file delete change event', done => {
const expected = joinPath(environmentService.backupWorkspaceHome!, 'settings.json');
const target = joinPath(localBackupsResource, 'settings.json');
testObject.onDidFilesChange(e => {
if (e.contains(expected, FileChangeType.DELETED)) {
done();
}
});
fileEventEmitter.fire([{ fileEventEmitter.fire([{
resource: target, resource: target,
type: FileChangeType.DELETED type: FileChangeType.DELETED
}]); }]);
if (triggered) {
assert.fail('event should not be triggered');
}
}); });
}); });
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册