提交 7e932c35 编写于 作者: S Sandeep Somavarapu

remote configuration file service

上级 1e201e8d
......@@ -12,7 +12,7 @@ import { RunOnceScheduler } from 'vs/base/common/async';
import { FileChangeType, FileChangesEvent, IFileService } from 'vs/platform/files/common/files';
import { ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels';
import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels';
import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration';
import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration';
import { IStoredWorkspaceFolder, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService';
import { WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
......@@ -24,6 +24,20 @@ import { IConfigurationModel } from 'vs/platform/configuration/common/configurat
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { hash } from 'vs/base/common/hash';
function whenProviderRegistered(scheme: string, fileService: IFileService): Promise<void> {
if (fileService.canHandleResource(URI.from({ scheme }))) {
return Promise.resolve();
}
return new Promise((c, e) => {
const disposable = fileService.onDidChangeFileSystemProviderRegistrations(e => {
if (e.scheme === scheme && e.added) {
disposable.dispose();
c();
}
});
});
}
export class UserConfiguration extends Disposable {
private readonly parser: ConfigurationModelParser;
......@@ -66,7 +80,7 @@ export class UserConfiguration extends Disposable {
export class RemoteUserConfiguration extends Disposable {
private readonly _cachedConfiguration: CachedRemoteUserConfiguration;
private readonly _configurationFileService: ConfigurationFileService;
private readonly _fileService: IFileService;
private _userConfiguration: FileServiceBasedRemoteUserConfiguration | CachedRemoteUserConfiguration;
private _userConfigurationInitializationPromise: Promise<ConfigurationModel> | null = null;
......@@ -76,15 +90,15 @@ export class RemoteUserConfiguration extends Disposable {
constructor(
remoteAuthority: string,
configurationCache: IConfigurationCache,
configurationFileService: ConfigurationFileService,
fileService: IFileService,
remoteAgentService: IRemoteAgentService
) {
super();
this._configurationFileService = configurationFileService;
this._fileService = fileService;
this._userConfiguration = this._cachedConfiguration = new CachedRemoteUserConfiguration(remoteAuthority, configurationCache);
remoteAgentService.getEnvironment().then(async environment => {
if (environment) {
const userConfiguration = this._register(new FileServiceBasedRemoteUserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._configurationFileService));
const userConfiguration = this._register(new FileServiceBasedRemoteUserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._fileService));
this._register(userConfiguration.onDidChangeConfiguration(configurationModel => this.onDidUserConfigurationChange(configurationModel)));
this._userConfigurationInitializationPromise = userConfiguration.initialize();
const configurationModel = await this._userConfigurationInitializationPromise;
......@@ -142,12 +156,12 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable {
constructor(
private readonly configurationResource: URI,
private readonly scopes: ConfigurationScope[] | undefined,
private readonly configurationFileService: ConfigurationFileService
private readonly fileService: IFileService
) {
super();
this.parser = new ConfigurationModelParser(this.configurationResource.toString(), this.scopes);
this._register(configurationFileService.onFileChanges(e => this.handleFileEvents(e)));
this._register(fileService.onFileChanges(e => this.handleFileEvents(e)));
this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50));
this._register(toDisposable(() => {
this.stopWatchingResource();
......@@ -156,7 +170,7 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable {
}
private watchResource(): void {
this.fileWatcherDisposable = this.configurationFileService.watch(this.configurationResource);
this.fileWatcherDisposable = this.fileService.watch(this.configurationResource);
}
private stopWatchingResource(): void {
......@@ -166,7 +180,7 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable {
private watchDirectory(): void {
const directory = resources.dirname(this.configurationResource);
this.directoryWatcherDisposable = this.configurationFileService.watch(directory);
this.directoryWatcherDisposable = this.fileService.watch(directory);
}
private stopWatchingDirectory(): void {
......@@ -175,15 +189,15 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable {
}
async initialize(): Promise<ConfigurationModel> {
const exists = await this.configurationFileService.exists(this.configurationResource);
const exists = await this.fileService.exists(this.configurationResource);
this.onResourceExists(exists);
return this.reload();
}
async reload(): Promise<ConfigurationModel> {
try {
const content = await this.configurationFileService.readFile(this.configurationResource);
this.parser.parseContent(content);
const content = await this.fileService.readFile(this.configurationResource);
this.parser.parseContent(content.value.toString());
return this.parser.configurationModel;
} catch (e) {
return new ConfigurationModel();
......@@ -279,7 +293,7 @@ class CachedRemoteUserConfiguration extends Disposable {
export class WorkspaceConfiguration extends Disposable {
private readonly _configurationFileService: ConfigurationFileService;
private readonly _fileService: IFileService;
private readonly _cachedConfiguration: CachedWorkspaceConfiguration;
private _workspaceConfiguration: IWorkspaceConfiguration;
private _workspaceConfigurationChangeDisposable: IDisposable = Disposable.None;
......@@ -293,10 +307,10 @@ export class WorkspaceConfiguration extends Disposable {
constructor(
configurationCache: IConfigurationCache,
configurationFileService: ConfigurationFileService
fileService: IFileService
) {
super();
this._configurationFileService = configurationFileService;
this._fileService = fileService;
this._workspaceConfiguration = this._cachedConfiguration = new CachedWorkspaceConfiguration(configurationCache);
}
......@@ -304,7 +318,7 @@ export class WorkspaceConfiguration extends Disposable {
this._workspaceIdentifier = workspaceIdentifier;
if (!(this._workspaceConfiguration instanceof FileServiceBasedWorkspaceConfiguration)) {
if (this._workspaceIdentifier.configPath.scheme === Schemas.file) {
this.switch(new FileServiceBasedWorkspaceConfiguration(this._configurationFileService));
this.switch(new FileServiceBasedWorkspaceConfiguration(this._fileService));
} else {
this.waitAndSwitch(this._workspaceIdentifier);
}
......@@ -339,9 +353,9 @@ export class WorkspaceConfiguration extends Disposable {
}
private async waitAndSwitch(workspaceIdentifier: IWorkspaceIdentifier): Promise<void> {
await this._configurationFileService.whenProviderRegistered(workspaceIdentifier.configPath.scheme);
await whenProviderRegistered(workspaceIdentifier.configPath.scheme, this._fileService);
if (!(this._workspaceConfiguration instanceof FileServiceBasedWorkspaceConfiguration)) {
const fileServiceBasedWorkspaceConfiguration = this._register(new FileServiceBasedWorkspaceConfiguration(this._configurationFileService));
const fileServiceBasedWorkspaceConfiguration = this._register(new FileServiceBasedWorkspaceConfiguration(this._fileService));
await fileServiceBasedWorkspaceConfiguration.load(workspaceIdentifier);
this.switch(fileServiceBasedWorkspaceConfiguration);
this._loaded = true;
......@@ -396,13 +410,13 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork
protected readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChange: Event<void> = this._onDidChange.event;
constructor(private configurationFileService: ConfigurationFileService) {
constructor(private fileService: IFileService) {
super();
this.workspaceConfigurationModelParser = new WorkspaceConfigurationModelParser('');
this.workspaceSettings = new ConfigurationModel();
this._register(configurationFileService.onFileChanges(e => this.handleWorkspaceFileEvents(e)));
this._register(fileService.onFileChanges(e => this.handleWorkspaceFileEvents(e)));
this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this._onDidChange.fire(), 50));
this.workspaceConfigWatcher = this._register(this.watchWorkspaceConfigurationFile());
}
......@@ -420,9 +434,10 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork
}
let contents = '';
try {
contents = await this.configurationFileService.readFile(this._workspaceIdentifier.configPath);
const content = await this.fileService.readFile(this._workspaceIdentifier.configPath);
contents = content.value.toString();
} catch (error) {
const exists = await this.configurationFileService.exists(this._workspaceIdentifier.configPath);
const exists = await this.fileService.exists(this._workspaceIdentifier.configPath);
if (exists) {
errors.onUnexpectedError(error);
}
......@@ -454,7 +469,7 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork
}
private watchWorkspaceConfigurationFile(): IDisposable {
return this._workspaceIdentifier ? this.configurationFileService.watch(this._workspaceIdentifier.configPath) : Disposable.None;
return this._workspaceIdentifier ? this.fileService.watch(this._workspaceIdentifier.configPath) : Disposable.None;
}
private handleWorkspaceFileEvents(event: FileChangesEvent): void {
......@@ -557,7 +572,7 @@ class FileServiceBasedFolderConfiguration extends Disposable implements IFolderC
protected readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChange: Event<void> = this._onDidChange.event;
constructor(protected readonly configurationFolder: URI, workbenchState: WorkbenchState, private configurationFileService: ConfigurationFileService) {
constructor(protected readonly configurationFolder: URI, workbenchState: WorkbenchState, private fileService: IFileService) {
super();
this.configurationNames = [FOLDER_SETTINGS_NAME /*First one should be settings */, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY];
......@@ -567,15 +582,16 @@ class FileServiceBasedFolderConfiguration extends Disposable implements IFolderC
this._cache = new ConfigurationModel();
this.changeEventTriggerScheduler = this._register(new RunOnceScheduler(() => this._onDidChange.fire(), 50));
this._register(configurationFileService.onFileChanges(e => this.handleWorkspaceFileEvents(e)));
this._register(fileService.onFileChanges(e => this.handleWorkspaceFileEvents(e)));
}
async loadConfiguration(): Promise<ConfigurationModel> {
const configurationContents = await Promise.all(this.configurationResources.map(async resource => {
try {
return await this.configurationFileService.readFile(resource);
const content = await this.fileService.readFile(resource);
return content.value.toString();
} catch (error) {
const exists = await this.configurationFileService.exists(resource);
const exists = await this.fileService.exists(resource);
if (exists) {
errors.onUnexpectedError(error);
}
......@@ -724,7 +740,7 @@ export class FolderConfiguration extends Disposable implements IFolderConfigurat
readonly workspaceFolder: IWorkspaceFolder,
configFolderRelativePath: string,
private readonly workbenchState: WorkbenchState,
configurationFileService: ConfigurationFileService,
fileService: IFileService,
configurationCache: IConfigurationCache
) {
super();
......@@ -732,13 +748,13 @@ export class FolderConfiguration extends Disposable implements IFolderConfigurat
this.configurationFolder = resources.joinPath(workspaceFolder.uri, configFolderRelativePath);
this.folderConfiguration = this.cachedFolderConfiguration = new CachedFolderConfiguration(workspaceFolder.uri, configFolderRelativePath, configurationCache);
if (workspaceFolder.uri.scheme === Schemas.file) {
this.folderConfiguration = new FileServiceBasedFolderConfiguration(this.configurationFolder, this.workbenchState, configurationFileService);
this.folderConfiguration = new FileServiceBasedFolderConfiguration(this.configurationFolder, this.workbenchState, fileService);
} else {
configurationFileService.whenProviderRegistered(workspaceFolder.uri.scheme)
whenProviderRegistered(workspaceFolder.uri.scheme, fileService)
.then(() => {
this.folderConfiguration.dispose();
this.folderConfigurationDisposable.dispose();
this.folderConfiguration = new FileServiceBasedFolderConfiguration(this.configurationFolder, this.workbenchState, configurationFileService);
this.folderConfiguration = new FileServiceBasedFolderConfiguration(this.configurationFolder, this.workbenchState, fileService);
this._register(this.folderConfiguration.onDidChange(e => this.onDidFolderConfigurationChange()));
this.onDidFolderConfigurationChange();
});
......
......@@ -14,7 +14,7 @@ import { IWorkspaceContextService, Workspace, WorkbenchState, IWorkspaceFolder,
import { ConfigurationChangeEvent, ConfigurationModel, DefaultConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { Configuration, WorkspaceConfigurationChangeEvent, AllKeysConfigurationChangeEvent } from 'vs/workbench/services/configuration/common/configurationModels';
import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration';
import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES } from 'vs/workbench/services/configuration/common/configuration';
import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings } from 'vs/platform/configuration/common/configurationRegistry';
import { IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceInitializationPayload, isSingleFolderWorkspaceInitializationPayload, ISingleFolderWorkspaceInitializationPayload, IEmptyWorkspaceInitializationPayload, useSlashForPath, getStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
......@@ -45,7 +45,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
private cachedFolderConfigs: ResourceMap<FolderConfiguration>;
private workspaceEditingQueue: Queue<void>;
private readonly configurationFileService: ConfigurationFileService;
private readonly fileService: IFileService;
protected readonly _onDidChangeConfiguration: Emitter<IConfigurationChangeEvent> = this._register(new Emitter<IConfigurationChangeEvent>());
public readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;
......@@ -76,16 +76,16 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
this.completeWorkspaceBarrier = new Barrier();
this.defaultConfiguration = new DefaultConfigurationModel();
this.configurationCache = configurationCache;
this.configurationFileService = new ConfigurationFileService(fileService);
this.fileService = fileService;
this._configuration = new Configuration(this.defaultConfiguration, new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ResourceMap(), new ConfigurationModel(), new ResourceMap<ConfigurationModel>(), this.workspace);
this.cachedFolderConfigs = new ResourceMap<FolderConfiguration>();
this.localUserConfiguration = this._register(new UserConfiguration(environmentService.settingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, fileService));
this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration)));
if (remoteAuthority) {
this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, this.configurationFileService, remoteAgentService));
this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, fileService, remoteAgentService));
this._register(this.remoteUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onRemoteUserConfigurationChanged(userConfiguration)));
}
this.workspaceConfiguration = this._register(new WorkspaceConfiguration(configurationCache, this.configurationFileService));
this.workspaceConfiguration = this._register(new WorkspaceConfiguration(configurationCache, fileService));
this._register(this.workspaceConfiguration.onDidUpdateConfiguration(() => {
this.onWorkspaceConfigurationChanged();
if (this.workspaceConfiguration.loaded) {
......@@ -610,7 +610,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
return Promise.all([...folders.map(folder => {
let folderConfiguration = this.cachedFolderConfigs.get(folder.uri);
if (!folderConfiguration) {
folderConfiguration = new FolderConfiguration(folder, FOLDER_CONFIG_FOLDER_NAME, this.getWorkbenchState(), this.configurationFileService, this.configurationCache);
folderConfiguration = new FolderConfiguration(folder, FOLDER_CONFIG_FOLDER_NAME, this.getWorkbenchState(), this.fileService, this.configurationCache);
this._register(folderConfiguration.onDidChange(() => this.onWorkspaceFolderConfigurationChanged(folder)));
this.cachedFolderConfigs.set(folder.uri, this._register(folderConfiguration));
}
......
......@@ -3,9 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IFileService } from 'vs/platform/files/common/files';
import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
export const FOLDER_CONFIG_FOLDER_NAME = '.vscode';
......@@ -39,38 +36,4 @@ export interface IConfigurationCache {
write(key: ConfigurationKey, content: string): Promise<void>;
remove(key: ConfigurationKey): Promise<void>;
}
export class ConfigurationFileService {
constructor(private readonly fileService: IFileService) { }
get onFileChanges() { return this.fileService.onFileChanges; }
whenProviderRegistered(scheme: string): Promise<void> {
if (this.fileService.canHandleResource(URI.from({ scheme }))) {
return Promise.resolve();
}
return new Promise((c, e) => {
const disposable = this.fileService.onDidChangeFileSystemProviderRegistrations(e => {
if (e.scheme === scheme && e.added) {
disposable.dispose();
c();
}
});
});
}
watch(resource: URI): IDisposable {
return this.fileService.watch(resource);
}
exists(resource: URI): Promise<boolean> {
return this.fileService.exists(resource);
}
readFile(resource: URI): Promise<string> {
return this.fileService.readFile(resource).then(content => content.value.toString());
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册