Merge from vscode 966b87dd4013be1a9c06e2b8334522ec61905cc2 (#4696)

This commit is contained in:
Anthony Dresser
2019-03-26 11:43:38 -07:00
committed by GitHub
parent b1393ae615
commit 0d8ef9583b
268 changed files with 5947 additions and 3422 deletions

View File

@@ -28,6 +28,7 @@ import { ITextModel } from 'vs/editor/common/model';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
import { withUndefinedAsNull, withNullAsUndefined } from 'vs/base/common/types';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
export const enum ConfigurationEditingErrorCode {
@@ -120,6 +121,7 @@ export class ConfigurationEditingService {
public _serviceBrand: any;
private queue: Queue<void>;
private remoteSettingsResource: URI | null;
constructor(
@IConfigurationService private readonly configurationService: IConfigurationService,
@@ -130,9 +132,15 @@ export class ConfigurationEditingService {
@ITextFileService private readonly textFileService: ITextFileService,
@INotificationService private readonly notificationService: INotificationService,
@IPreferencesService private readonly preferencesService: IPreferencesService,
@IEditorService private readonly editorService: IEditorService
@IEditorService private readonly editorService: IEditorService,
@IRemoteAgentService remoteAgentService: IRemoteAgentService
) {
this.queue = new Queue<void>();
remoteAgentService.getEnvironment().then(environment => {
if (environment) {
this.remoteSettingsResource = environment.appSettingsPath;
}
});
}
writeConfiguration(target: ConfigurationTarget, value: IConfigurationValue, options: IConfigurationEditingOptions = {}): Promise<void> {
@@ -458,7 +466,7 @@ export class ConfigurationEditingService {
if (config.key) {
const standaloneConfigurationKeys = Object.keys(WORKSPACE_STANDALONE_CONFIGURATIONS);
for (const key of standaloneConfigurationKeys) {
const resource = this.getConfigurationFileResource(target, WORKSPACE_STANDALONE_CONFIGURATIONS[key], overrides.resource);
const resource = this.getConfigurationFileResource(target, config, WORKSPACE_STANDALONE_CONFIGURATIONS[key], overrides.resource);
// Check for prefix
if (config.key === key) {
@@ -478,10 +486,10 @@ export class ConfigurationEditingService {
let key = config.key;
let jsonPath = overrides.overrideIdentifier ? [keyFromOverrideIdentifier(overrides.overrideIdentifier), key] : [key];
if (target === ConfigurationTarget.USER) {
return { key, jsonPath, value: config.value, resource: URI.file(this.environmentService.appSettingsPath), target };
return { key, jsonPath, value: config.value, resource: withNullAsUndefined(this.getConfigurationFileResource(target, config, '', null)), target };
}
const resource = this.getConfigurationFileResource(target, FOLDER_SETTINGS_PATH, overrides.resource);
const resource = this.getConfigurationFileResource(target, config, FOLDER_SETTINGS_PATH, overrides.resource);
if (this.isWorkspaceConfigurationResource(resource)) {
jsonPath = ['settings', ...jsonPath];
}
@@ -493,8 +501,17 @@ export class ConfigurationEditingService {
return !!(workspace.configuration && resource && workspace.configuration.fsPath === resource.fsPath);
}
private getConfigurationFileResource(target: ConfigurationTarget, relativePath: string, resource: URI | null | undefined): URI | null {
private getConfigurationFileResource(target: ConfigurationTarget, config: IConfigurationValue, relativePath: string, resource: URI | null | undefined): URI | null {
if (target === ConfigurationTarget.USER_LOCAL) {
return URI.file(this.environmentService.appSettingsPath);
}
if (target === ConfigurationTarget.USER_REMOTE) {
return this.remoteSettingsResource;
}
if (target === ConfigurationTarget.USER) {
if (this.configurationService.inspect(config.key).userRemote !== undefined) {
return this.remoteSettingsResource;
}
return URI.file(this.environmentService.appSettingsPath);
}

View File

@@ -131,13 +131,14 @@ export class Configuration extends BaseConfiguration {
constructor(
defaults: ConfigurationModel,
user: ConfigurationModel,
localUser: ConfigurationModel,
remoteUser: ConfigurationModel,
workspaceConfiguration: ConfigurationModel,
folders: ResourceMap<ConfigurationModel>,
memoryConfiguration: ConfigurationModel,
memoryConfigurationByResource: ResourceMap<ConfigurationModel>,
private readonly _workspace?: Workspace) {
super(defaults, user, workspaceConfiguration, folders, memoryConfiguration, memoryConfigurationByResource);
super(defaults, localUser, remoteUser, workspaceConfiguration, folders, memoryConfiguration, memoryConfigurationByResource);
}
getValue(key: string | undefined, overrides: IConfigurationOverrides = {}): any {
@@ -164,17 +165,26 @@ export class Configuration extends BaseConfiguration {
return super.keys(this._workspace);
}
compareAndUpdateUserConfiguration(user: ConfigurationModel): ConfigurationChangeEvent {
const { added, updated, removed } = compare(this.user, user);
compareAndUpdateLocalUserConfiguration(user: ConfigurationModel): ConfigurationChangeEvent {
const { added, updated, removed } = compare(this.localUserConfiguration, user);
let changedKeys = [...added, ...updated, ...removed];
if (changedKeys.length) {
super.updateUserConfiguration(user);
super.updateLocalUserConfiguration(user);
}
return new ConfigurationChangeEvent().change(changedKeys);
}
compareAndUpdateRemoteUserConfiguration(user: ConfigurationModel): ConfigurationChangeEvent {
const { added, updated, removed } = compare(this.remoteUserConfiguration, user);
let changedKeys = [...added, ...updated, ...removed];
if (changedKeys.length) {
super.updateRemoteUserConfiguration(user);
}
return new ConfigurationChangeEvent().change(changedKeys);
}
compareAndUpdateWorkspaceConfiguration(workspaceConfiguration: ConfigurationModel): ConfigurationChangeEvent {
const { added, updated, removed } = compare(this.workspace, workspaceConfiguration);
const { added, updated, removed } = compare(this.workspaceConfiguration, workspaceConfiguration);
let changedKeys = [...added, ...updated, ...removed];
if (changedKeys.length) {
super.updateWorkspaceConfiguration(workspaceConfiguration);
@@ -183,7 +193,7 @@ export class Configuration extends BaseConfiguration {
}
compareAndUpdateFolderConfiguration(resource: URI, folderConfiguration: ConfigurationModel): ConfigurationChangeEvent {
const currentFolderConfiguration = this.folders.get(resource);
const currentFolderConfiguration = this.folderConfigurations.get(resource);
if (currentFolderConfiguration) {
const { added, updated, removed } = compare(currentFolderConfiguration, folderConfiguration);
let changedKeys = [...added, ...updated, ...removed];
@@ -202,7 +212,7 @@ export class Configuration extends BaseConfiguration {
// Do not remove workspace configuration
return new ConfigurationChangeEvent();
}
const folderConfig = this.folders.get(folder);
const folderConfig = this.folderConfigurations.get(folder);
if (!folderConfig) {
throw new Error('Unknown folder');
}

View File

@@ -25,7 +25,145 @@ import { extname, join } from 'vs/base/common/path';
import { equals } from 'vs/base/common/objects';
import { Schemas } from 'vs/base/common/network';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IConfigurationModel } from 'vs/platform/configuration/common/configuration';
import { IConfigurationModel, compare } from 'vs/platform/configuration/common/configuration';
import { FileServiceBasedUserConfiguration, NodeBasedUserConfiguration } from 'vs/platform/configuration/node/configuration';
export class LocalUserConfiguration extends Disposable {
private userConfiguration: NodeBasedUserConfiguration | FileServiceBasedUserConfiguration;
private readonly _onDidChangeConfiguration: Emitter<ConfigurationModel> = this._register(new Emitter<ConfigurationModel>());
public readonly onDidChangeConfiguration: Event<ConfigurationModel> = this._onDidChangeConfiguration.event;
constructor(
environmentService: IEnvironmentService
) {
super();
this.userConfiguration = this._register(new NodeBasedUserConfiguration(environmentService.appSettingsPath));
this._register(this.userConfiguration.onDidChangeConfiguration(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)));
}
initialize(): Promise<ConfigurationModel> {
return this.userConfiguration.initialize();
}
reload(): Promise<ConfigurationModel> {
return this.userConfiguration.reload();
}
async adopt(fileService: IFileService): Promise<ConfigurationModel | null> {
return null;
}
}
export class RemoteUserConfiguration extends Disposable {
private readonly _cachedConfiguration: CachedUserConfiguration;
private _userConfiguration: FileServiceBasedUserConfiguration | CachedUserConfiguration;
private readonly _onDidChangeConfiguration: Emitter<ConfigurationModel> = this._register(new Emitter<ConfigurationModel>());
public readonly onDidChangeConfiguration: Event<ConfigurationModel> = this._onDidChangeConfiguration.event;
constructor(
remoteAuthority: string,
environmentService: IEnvironmentService
) {
super();
this._userConfiguration = this._cachedConfiguration = new CachedUserConfiguration(remoteAuthority, environmentService);
}
initialize(): Promise<ConfigurationModel> {
return this._userConfiguration.initialize();
}
reload(): Promise<ConfigurationModel> {
return this._userConfiguration.reload();
}
async adopt(configurationResource: URI | null, fileService: IFileService): Promise<ConfigurationModel | null> {
if (this._userConfiguration instanceof CachedUserConfiguration) {
const oldConfigurationModel = this._userConfiguration.getConfigurationModel();
let newConfigurationModel = new ConfigurationModel();
if (configurationResource) {
this._userConfiguration = new FileServiceBasedUserConfiguration(configurationResource, fileService);
this._register(this._userConfiguration.onDidChangeConfiguration(configurationModel => this.onDidUserConfigurationChange(configurationModel)));
newConfigurationModel = await this._userConfiguration.initialize();
}
const { added, updated, removed } = compare(oldConfigurationModel, newConfigurationModel);
if (added.length > 0 || updated.length > 0 || removed.length > 0) {
this.updateCache(newConfigurationModel);
return newConfigurationModel;
}
}
return null;
}
private onDidUserConfigurationChange(configurationModel: ConfigurationModel): void {
this.updateCache(configurationModel);
this._onDidChangeConfiguration.fire(configurationModel);
}
private updateCache(configurationModel: ConfigurationModel): Promise<void> {
return this._cachedConfiguration.updateConfiguration(configurationModel);
}
}
class CachedUserConfiguration extends Disposable {
private readonly _onDidChange: Emitter<ConfigurationModel> = this._register(new Emitter<ConfigurationModel>());
readonly onDidChange: Event<ConfigurationModel> = this._onDidChange.event;
private readonly cachedFolderPath: string;
private readonly cachedConfigurationPath: string;
private configurationModel: ConfigurationModel;
constructor(
remoteAuthority: string,
private environmentService: IEnvironmentService
) {
super();
this.cachedFolderPath = join(this.environmentService.userDataPath, 'CachedConfigurations', 'user', remoteAuthority);
this.cachedConfigurationPath = join(this.cachedFolderPath, 'configuration.json');
this.configurationModel = new ConfigurationModel();
}
getConfigurationModel(): ConfigurationModel {
return this.configurationModel;
}
initialize(): Promise<ConfigurationModel> {
return this.reload();
}
reload(): Promise<ConfigurationModel> {
return pfs.readFile(this.cachedConfigurationPath)
.then(content => content.toString(), () => '')
.then(content => {
try {
const parsed: IConfigurationModel = JSON.parse(content);
this.configurationModel = new ConfigurationModel(parsed.contents, parsed.keys, parsed.overrides);
} catch (e) {
}
return this.configurationModel;
});
}
updateConfiguration(configurationModel: ConfigurationModel): Promise<void> {
const raw = JSON.stringify(configurationModel.toJSON());
return this.createCachedFolder().then(created => {
if (created) {
return configurationModel.keys.length ? pfs.writeFile(this.cachedConfigurationPath, raw) : pfs.rimraf(this.cachedFolderPath);
}
return undefined;
});
}
private createCachedFolder(): Promise<boolean> {
return Promise.resolve(pfs.exists(this.cachedFolderPath))
.then(undefined, () => false)
.then(exists => exists ? exists : pfs.mkdirp(this.cachedFolderPath).then(() => true, () => false));
}
}
export interface IWorkspaceIdentifier {
id: string;

View File

@@ -28,14 +28,15 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
import product from 'vs/platform/product/node/product';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ConfigurationEditingService } from 'vs/workbench/services/configuration/common/configurationEditingService';
import { WorkspaceConfiguration, FolderConfiguration } from 'vs/workbench/services/configuration/node/configuration';
import { WorkspaceConfiguration, FolderConfiguration, RemoteUserConfiguration, LocalUserConfiguration } from 'vs/workbench/services/configuration/node/configuration';
import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService';
import { UserConfiguration } from 'vs/platform/configuration/node/configuration';
import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema';
import { localize } from 'vs/nls';
import { isEqual, dirname } from 'vs/base/common/resources';
import { mark } from 'vs/base/common/performance';
import { Schemas } from 'vs/base/common/network';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
export class WorkspaceService extends Disposable implements IConfigurationService, IWorkspaceContextService {
@@ -45,7 +46,8 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
private completeWorkspaceBarrier: Barrier;
private _configuration: Configuration;
private defaultConfiguration: DefaultConfigurationModel;
private userConfiguration: UserConfiguration;
private localUserConfiguration: LocalUserConfiguration;
private remoteUserConfiguration: RemoteUserConfiguration | null = null;
private workspaceConfiguration: WorkspaceConfiguration;
private cachedFolderConfigs: ResourceMap<FolderConfiguration>;
@@ -67,14 +69,18 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
private configurationEditingService: ConfigurationEditingService;
private jsonEditingService: JSONEditingService;
constructor(private environmentService: IEnvironmentService, private workspaceSettingsRootFolder: string = FOLDER_CONFIG_FOLDER_NAME) {
constructor(configuration: IWindowConfiguration, private environmentService: IEnvironmentService, private remoteAgentService: IRemoteAgentService, private workspaceSettingsRootFolder: string = FOLDER_CONFIG_FOLDER_NAME) {
super();
this.completeWorkspaceBarrier = new Barrier();
this.defaultConfiguration = new DefaultConfigurationModel();
this.userConfiguration = this._register(new UserConfiguration(environmentService.appSettingsPath));
this.localUserConfiguration = this._register(new LocalUserConfiguration(environmentService));
this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration)));
if (configuration.remoteAuthority) {
this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(configuration.remoteAuthority, environmentService));
this._register(this.remoteUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onRemoteUserConfigurationChanged(userConfiguration)));
}
this.workspaceConfiguration = this._register(new WorkspaceConfiguration(environmentService));
this._register(this.userConfiguration.onDidChangeConfiguration(userConfiguration => this.onUserConfigurationChanged(userConfiguration)));
this._register(this.workspaceConfiguration.onDidUpdateConfiguration(() => this.onWorkspaceConfigurationChanged()));
this._register(Registry.as<IConfigurationRegistry>(Extensions.Configuration).onDidSchemaChange(e => this.registerConfigurationSchemas()));
@@ -254,8 +260,8 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
return this.reloadWorkspaceFolderConfiguration(folder, key);
}
return this.reloadUserConfiguration()
.then(userConfigurationModel => this.reloadWorkspaceConfiguration()
.then(() => this.loadConfiguration(userConfigurationModel)));
.then(({ local, remote }) => this.reloadWorkspaceConfiguration()
.then(() => this.loadConfiguration(local, remote)));
}
inspect<T>(key: string, overrides?: IConfigurationOverrides): {
@@ -289,6 +295,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
acquireFileService(fileService: IFileService): void {
this.fileService = fileService;
const changedWorkspaceFolders: IWorkspaceFolder[] = [];
this.localUserConfiguration.adopt(fileService);
Promise.all([this.workspaceConfiguration.adopt(fileService), ...this.cachedFolderConfigs.values()
.map(folderConfiguration => folderConfiguration.adopt(fileService)
.then(result => {
@@ -306,6 +313,15 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
}
this.releaseWorkspaceBarrier();
});
if (this.remoteUserConfiguration) {
this.remoteAgentService.getEnvironment()
.then(environment => this.remoteUserConfiguration!.adopt(environment ? environment.appSettingsPath : null, fileService)
.then(changedModel => {
if (changedModel) {
this.onRemoteUserConfigurationChanged(changedModel);
}
}));
}
}
acquireInstantiationService(instantiationService: IInstantiationService): void {
@@ -425,12 +441,18 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
private initializeConfiguration(): Promise<void> {
this.registerConfigurationSchemas();
return this.userConfiguration.initialize()
.then(userConfigurationModel => this.loadConfiguration(userConfigurationModel));
return this.initializeUserConfiguration()
.then(({ local, remote }) => this.loadConfiguration(local, remote));
}
private reloadUserConfiguration(key?: string): Promise<ConfigurationModel> {
return this.userConfiguration.reload();
private initializeUserConfiguration(): Promise<{ local: ConfigurationModel, remote: ConfigurationModel }> {
return Promise.all([this.localUserConfiguration.initialize(), this.remoteUserConfiguration ? this.remoteUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel())])
.then(([local, remote]) => ({ local, remote }));
}
private reloadUserConfiguration(key?: string): Promise<{ local: ConfigurationModel, remote: ConfigurationModel }> {
return Promise.all([this.localUserConfiguration.reload(), this.remoteUserConfiguration ? this.remoteUserConfiguration.reload() : Promise.resolve(new ConfigurationModel())])
.then(([local, remote]) => ({ local, remote }));
}
private reloadWorkspaceConfiguration(key?: string): Promise<void> {
@@ -448,7 +470,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
return this.onWorkspaceFolderConfigurationChanged(folder, key);
}
private loadConfiguration(userConfigurationModel: ConfigurationModel): Promise<void> {
private loadConfiguration(userConfigurationModel: ConfigurationModel, remoteUserConfigurationModel: ConfigurationModel): Promise<void> {
// reset caches
this.cachedFolderConfigs = new ResourceMap<FolderConfiguration>();
@@ -461,7 +483,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
folderConfigurations.forEach((folderConfiguration, index) => folderConfigurationModels.set(folders[index].uri, folderConfiguration));
const currentConfiguration = this._configuration;
this._configuration = new Configuration(this.defaultConfiguration, userConfigurationModel, workspaceConfiguration, folderConfigurationModels, new ConfigurationModel(), new ResourceMap<ConfigurationModel>(), this.workspace);
this._configuration = new Configuration(this.defaultConfiguration, userConfigurationModel, remoteUserConfigurationModel, workspaceConfiguration, folderConfigurationModels, new ConfigurationModel(), new ResourceMap<ConfigurationModel>(), this.workspace);
if (currentConfiguration) {
const changedKeys = this._configuration.compare(currentConfiguration);
@@ -528,8 +550,13 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
}
}
private onUserConfigurationChanged(userConfiguration: ConfigurationModel): void {
const keys = this._configuration.compareAndUpdateUserConfiguration(userConfiguration);
private onLocalUserConfigurationChanged(userConfiguration: ConfigurationModel): void {
const keys = this._configuration.compareAndUpdateLocalUserConfiguration(userConfiguration);
this.triggerConfigurationChange(keys, ConfigurationTarget.USER);
}
private onRemoteUserConfigurationChanged(userConfiguration: ConfigurationModel): void {
const keys = this._configuration.compareAndUpdateRemoteUserConfiguration(userConfiguration);
this.triggerConfigurationChange(keys, ConfigurationTarget.USER);
}
@@ -618,7 +645,13 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
.then(() => {
switch (target) {
case ConfigurationTarget.USER:
return this.reloadUserConfiguration().then(_ => Promise.resolve());
return this.reloadUserConfiguration()
.then(({ local, remote }) => {
this.onLocalUserConfigurationChanged(local);
if (this.remoteUserConfiguration) {
this.onRemoteUserConfigurationChanged(remote);
}
});
case ConfigurationTarget.WORKSPACE:
return this.reloadWorkspaceConfiguration();
case ConfigurationTarget.WORKSPACE_FOLDER:
@@ -670,9 +703,9 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
case ConfigurationTarget.DEFAULT:
return this._configuration.defaults.contents;
case ConfigurationTarget.USER:
return this._configuration.user.contents;
return this._configuration.userConfiguration.contents;
case ConfigurationTarget.WORKSPACE:
return this._configuration.workspace.contents;
return this._configuration.workspaceConfiguration.contents;
}
return {};
}

View File

@@ -201,7 +201,7 @@ suite('AllKeysConfigurationChangeEvent', () => {
test('changeEvent affects keys for any resource', () => {
const configuraiton = new Configuration(new ConfigurationModel({}, ['window.title', 'window.zoomLevel', 'window.restoreFullscreen', 'workbench.editor.enablePreview', 'window.restoreWindows']),
new ConfigurationModel(), new ConfigurationModel(), new ResourceMap(), new ConfigurationModel(), new ResourceMap(), null!);
new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ResourceMap(), new ConfigurationModel(), new ResourceMap(), null!);
let testObject = new AllKeysConfigurationChangeEvent(configuraiton, ConfigurationTarget.USER, null);
assert.deepEqual(testObject.affectedKeys, ['window.title', 'window.zoomLevel', 'window.restoreFullscreen', 'workbench.editor.enablePreview', 'window.restoreWindows']);

View File

@@ -36,6 +36,9 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
import { CommandService } from 'vs/workbench/services/commands/common/commandService';
import { URI } from 'vs/base/common/uri';
import { createHash } from 'crypto';
import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
class SettingsTestEnvironmentService extends EnvironmentService {
@@ -100,7 +103,9 @@ suite('ConfigurationEditingService', () => {
instantiationService = <TestInstantiationService>workbenchInstantiationService();
const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile);
instantiationService.stub(IEnvironmentService, environmentService);
const workspaceService = new WorkspaceService(environmentService);
const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {});
instantiationService.stub(IRemoteAgentService, remoteAgentService);
const workspaceService = new WorkspaceService(<IWindowConfiguration>{}, environmentService, remoteAgentService);
instantiationService.stub(IWorkspaceContextService, workspaceService);
return workspaceService.initialize(noWorkspace ? { id: '' } : { folder: URI.file(workspaceDir), id: createHash('md5').update(URI.file(workspaceDir).toString()).digest('hex') }).then(() => {
instantiationService.stub(IConfigurationService, workspaceService);

View File

@@ -37,6 +37,10 @@ import { Schemas } from 'vs/base/common/network';
import { originalFSPath } from 'vs/base/common/resources';
import { isLinux } from 'vs/base/common/platform';
import { IWorkspaceIdentifier } from 'vs/workbench/services/configuration/node/configuration';
import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl';
import { RemoteAuthorityResolverService } from 'vs/platform/remote/electron-browser/remoteAuthorityResolverService';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
class SettingsTestEnvironmentService extends EnvironmentService {