mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 31e03b8ffbb218a87e3941f2b63a249f061fe0e4 (#4986)
This commit is contained in:
@@ -9,9 +9,10 @@ import * as arrays from 'vs/base/common/arrays';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { OVERRIDE_PROPERTY_PATTERN, ConfigurationScope, IConfigurationRegistry, Extensions, IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IOverrides, overrideIdentifierFromKey, addToValueTree, toValuesTree, IConfigurationModel, getConfigurationValue, IConfigurationOverrides, IConfigurationData, getDefaultValues, getConfigurationKeys, IConfigurationChangeEvent, ConfigurationTarget, removeFromValueTree, toOverrides } from 'vs/platform/configuration/common/configuration';
|
||||
import { Workspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
|
||||
export class ConfigurationModel implements IConfigurationModel {
|
||||
|
||||
@@ -195,10 +196,11 @@ export class DefaultConfigurationModel extends ConfigurationModel {
|
||||
|
||||
export class ConfigurationModelParser {
|
||||
|
||||
private _raw: any = null;
|
||||
private _configurationModel: ConfigurationModel | null = null;
|
||||
private _parseErrors: any[] = [];
|
||||
|
||||
constructor(protected readonly _name: string) { }
|
||||
constructor(protected readonly _name: string, private _scopes?: ConfigurationScope[]) { }
|
||||
|
||||
get configurationModel(): ConfigurationModel {
|
||||
return this._configurationModel || new ConfigurationModel();
|
||||
@@ -208,15 +210,26 @@ export class ConfigurationModelParser {
|
||||
return this._parseErrors;
|
||||
}
|
||||
|
||||
public parse(content: string | null | undefined): void {
|
||||
public parseContent(content: string | null | undefined): void {
|
||||
if (content) {
|
||||
const raw = this.parseContent(content);
|
||||
const configurationModel = this.parseRaw(raw);
|
||||
this._configurationModel = new ConfigurationModel(configurationModel.contents, configurationModel.keys, configurationModel.overrides);
|
||||
const raw = this.doParseContent(content);
|
||||
this.parseRaw(raw);
|
||||
}
|
||||
}
|
||||
|
||||
protected parseContent(content: string): any {
|
||||
public parseRaw(raw: any): void {
|
||||
this._raw = raw;
|
||||
const configurationModel = this.doParseRaw(raw);
|
||||
this._configurationModel = new ConfigurationModel(configurationModel.contents, configurationModel.keys, configurationModel.overrides);
|
||||
}
|
||||
|
||||
public parse(): void {
|
||||
if (this._raw) {
|
||||
this.parseRaw(this._raw);
|
||||
}
|
||||
}
|
||||
|
||||
protected doParseContent(content: string): any {
|
||||
let raw: any = {};
|
||||
let currentProperty: string | null = null;
|
||||
let currentParent: any = [];
|
||||
@@ -273,12 +286,36 @@ export class ConfigurationModelParser {
|
||||
return raw;
|
||||
}
|
||||
|
||||
protected parseRaw(raw: any): IConfigurationModel {
|
||||
protected doParseRaw(raw: any): IConfigurationModel {
|
||||
if (this._scopes) {
|
||||
const configurationProperties = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationProperties();
|
||||
raw = this.filterByScope(raw, configurationProperties, true, this._scopes);
|
||||
}
|
||||
const contents = toValuesTree(raw, message => console.error(`Conflict in settings file ${this._name}: ${message}`));
|
||||
const keys = Object.keys(raw);
|
||||
const overrides: IOverrides[] = toOverrides(raw, message => console.error(`Conflict in settings file ${this._name}: ${message}`));
|
||||
return { contents, keys, overrides };
|
||||
}
|
||||
|
||||
private filterByScope(properties: {}, configurationProperties: { [qualifiedKey: string]: IConfigurationPropertySchema }, filterOverriddenProperties: boolean, scopes: ConfigurationScope[]): {} {
|
||||
const result = {};
|
||||
for (let key in properties) {
|
||||
if (OVERRIDE_PROPERTY_PATTERN.test(key) && filterOverriddenProperties) {
|
||||
result[key] = this.filterByScope(properties[key], configurationProperties, false, scopes);
|
||||
} else {
|
||||
const scope = this.getScope(key, configurationProperties);
|
||||
if (scopes.indexOf(scope) !== -1) {
|
||||
result[key] = properties[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private getScope(key: string, configurationProperties: { [qualifiedKey: string]: IConfigurationPropertySchema }): ConfigurationScope {
|
||||
const propertySchema = configurationProperties[key];
|
||||
return propertySchema && typeof propertySchema.scope !== 'undefined' ? propertySchema.scope : ConfigurationScope.WINDOW;
|
||||
}
|
||||
}
|
||||
|
||||
export class Configuration {
|
||||
|
||||
@@ -27,7 +27,7 @@ export class NodeBasedUserConfiguration extends Disposable {
|
||||
this.userConfigModelWatcher = new ConfigWatcher(this.settingsPath, {
|
||||
changeBufferDelay: 300, onError: error => onUnexpectedError(error), defaultConfig: new ConfigurationModelParser(this.settingsPath), parse: (content: string, parseErrors: any[]) => {
|
||||
const userConfigModelParser = new ConfigurationModelParser(this.settingsPath);
|
||||
userConfigModelParser.parse(content);
|
||||
userConfigModelParser.parseContent(content);
|
||||
parseErrors = [...userConfigModelParser.errors];
|
||||
return userConfigModelParser;
|
||||
}, initCallback: () => c(undefined)
|
||||
|
||||
@@ -9,7 +9,6 @@ import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IConfigurationService, IConfigurationChangeEvent, IConfigurationOverrides, ConfigurationTarget, compare, isConfigurationOverrides, IConfigurationData } from 'vs/platform/configuration/common/configuration';
|
||||
import { DefaultConfigurationModel, Configuration, ConfigurationChangeEvent, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { NodeBasedUserConfiguration } from 'vs/platform/configuration/node/configuration';
|
||||
|
||||
@@ -24,11 +23,11 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
|
||||
readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;
|
||||
|
||||
constructor(
|
||||
@IEnvironmentService environmentService: IEnvironmentService
|
||||
configurationPath: string
|
||||
) {
|
||||
super();
|
||||
|
||||
this.userConfiguration = this._register(new NodeBasedUserConfiguration(environmentService.appSettingsPath));
|
||||
this.userConfiguration = this._register(new NodeBasedUserConfiguration(configurationPath));
|
||||
|
||||
// Initialize
|
||||
const defaults = new DefaultConfigurationModel();
|
||||
|
||||
@@ -250,10 +250,10 @@ suite('CustomConfigurationModel', () => {
|
||||
|
||||
test('simple merge using models', () => {
|
||||
let base = new ConfigurationModelParser('base');
|
||||
base.parse(JSON.stringify({ 'a': 1, 'b': 2 }));
|
||||
base.parseContent(JSON.stringify({ 'a': 1, 'b': 2 }));
|
||||
|
||||
let add = new ConfigurationModelParser('add');
|
||||
add.parse(JSON.stringify({ 'a': 3, 'c': 4 }));
|
||||
add.parseContent(JSON.stringify({ 'a': 3, 'c': 4 }));
|
||||
|
||||
let result = base.configurationModel.merge(add.configurationModel);
|
||||
assert.deepEqual(result.contents, { 'a': 3, 'b': 2, 'c': 4 });
|
||||
@@ -261,14 +261,14 @@ suite('CustomConfigurationModel', () => {
|
||||
|
||||
test('simple merge with an undefined contents', () => {
|
||||
let base = new ConfigurationModelParser('base');
|
||||
base.parse(JSON.stringify({ 'a': 1, 'b': 2 }));
|
||||
base.parseContent(JSON.stringify({ 'a': 1, 'b': 2 }));
|
||||
let add = new ConfigurationModelParser('add');
|
||||
let result = base.configurationModel.merge(add.configurationModel);
|
||||
assert.deepEqual(result.contents, { 'a': 1, 'b': 2 });
|
||||
|
||||
base = new ConfigurationModelParser('base');
|
||||
add = new ConfigurationModelParser('add');
|
||||
add.parse(JSON.stringify({ 'a': 1, 'b': 2 }));
|
||||
add.parseContent(JSON.stringify({ 'a': 1, 'b': 2 }));
|
||||
result = base.configurationModel.merge(add.configurationModel);
|
||||
assert.deepEqual(result.contents, { 'a': 1, 'b': 2 });
|
||||
|
||||
@@ -280,25 +280,25 @@ suite('CustomConfigurationModel', () => {
|
||||
|
||||
test('Recursive merge using config models', () => {
|
||||
let base = new ConfigurationModelParser('base');
|
||||
base.parse(JSON.stringify({ 'a': { 'b': 1 } }));
|
||||
base.parseContent(JSON.stringify({ 'a': { 'b': 1 } }));
|
||||
let add = new ConfigurationModelParser('add');
|
||||
add.parse(JSON.stringify({ 'a': { 'b': 2 } }));
|
||||
add.parseContent(JSON.stringify({ 'a': { 'b': 2 } }));
|
||||
let result = base.configurationModel.merge(add.configurationModel);
|
||||
assert.deepEqual(result.contents, { 'a': { 'b': 2 } });
|
||||
});
|
||||
|
||||
test('Test contents while getting an existing property', () => {
|
||||
let testObject = new ConfigurationModelParser('test');
|
||||
testObject.parse(JSON.stringify({ 'a': 1 }));
|
||||
testObject.parseContent(JSON.stringify({ 'a': 1 }));
|
||||
assert.deepEqual(testObject.configurationModel.getValue('a'), 1);
|
||||
|
||||
testObject.parse(JSON.stringify({ 'a': { 'b': 1 } }));
|
||||
testObject.parseContent(JSON.stringify({ 'a': { 'b': 1 } }));
|
||||
assert.deepEqual(testObject.configurationModel.getValue('a'), { 'b': 1 });
|
||||
});
|
||||
|
||||
test('Test contents are undefined for non existing properties', () => {
|
||||
const testObject = new ConfigurationModelParser('test');
|
||||
testObject.parse(JSON.stringify({
|
||||
testObject.parseContent(JSON.stringify({
|
||||
awesome: true
|
||||
}));
|
||||
|
||||
@@ -313,7 +313,7 @@ suite('CustomConfigurationModel', () => {
|
||||
|
||||
test('Test configWithOverrides gives all content merged with overrides', () => {
|
||||
const testObject = new ConfigurationModelParser('test');
|
||||
testObject.parse(JSON.stringify({ 'a': 1, 'c': 1, '[b]': { 'a': 2 } }));
|
||||
testObject.parseContent(JSON.stringify({ 'a': 1, 'c': 1, '[b]': { 'a': 2 } }));
|
||||
|
||||
assert.deepEqual(testObject.configurationModel.override('b').contents, { 'a': 2, 'c': 1, '[b]': { 'a': 2 } });
|
||||
});
|
||||
@@ -326,17 +326,17 @@ suite('CustomConfigurationModel', () => {
|
||||
|
||||
test('Test update with empty data', () => {
|
||||
const testObject = new ConfigurationModelParser('test');
|
||||
testObject.parse('');
|
||||
testObject.parseContent('');
|
||||
|
||||
assert.deepEqual(testObject.configurationModel.contents, {});
|
||||
assert.deepEqual(testObject.configurationModel.keys, []);
|
||||
|
||||
testObject.parse(null!);
|
||||
testObject.parseContent(null!);
|
||||
|
||||
assert.deepEqual(testObject.configurationModel.contents, {});
|
||||
assert.deepEqual(testObject.configurationModel.keys, []);
|
||||
|
||||
testObject.parse(undefined!);
|
||||
testObject.parseContent(undefined!);
|
||||
|
||||
assert.deepEqual(testObject.configurationModel.contents, {});
|
||||
assert.deepEqual(testObject.configurationModel.keys, []);
|
||||
@@ -472,7 +472,7 @@ suite('Configuration', () => {
|
||||
|
||||
test('Test update value', () => {
|
||||
const parser = new ConfigurationModelParser('test');
|
||||
parser.parse(JSON.stringify({ 'a': 1 }));
|
||||
parser.parseContent(JSON.stringify({ 'a': 1 }));
|
||||
const testObject: Configuration = new Configuration(parser.configurationModel, new ConfigurationModel());
|
||||
|
||||
testObject.updateValue('a', 2);
|
||||
@@ -482,7 +482,7 @@ suite('Configuration', () => {
|
||||
|
||||
test('Test update value after inspect', () => {
|
||||
const parser = new ConfigurationModelParser('test');
|
||||
parser.parse(JSON.stringify({ 'a': 1 }));
|
||||
parser.parseContent(JSON.stringify({ 'a': 1 }));
|
||||
const testObject: Configuration = new Configuration(parser.configurationModel, new ConfigurationModel());
|
||||
|
||||
testObject.inspect('a', {}, undefined);
|
||||
|
||||
@@ -10,29 +10,17 @@ import * as fs from 'fs';
|
||||
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ConfigurationService } from 'vs/platform/configuration/node/configurationService';
|
||||
import { ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { parseArgs } from 'vs/platform/environment/node/argv';
|
||||
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import * as uuid from 'vs/base/common/uuid';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { testFile } from 'vs/base/test/node/utils';
|
||||
|
||||
class SettingsTestEnvironmentService extends EnvironmentService {
|
||||
|
||||
constructor(args: ParsedArgs, _execPath: string, private customAppSettingsHome: string) {
|
||||
super(args, _execPath);
|
||||
}
|
||||
|
||||
get appSettingsPath(): string { return this.customAppSettingsHome; }
|
||||
}
|
||||
|
||||
suite('ConfigurationService - Node', () => {
|
||||
|
||||
test('simple', async () => {
|
||||
const res = await testFile('config', 'config.json');
|
||||
fs.writeFileSync(res.testFile, '{ "foo": "bar" }');
|
||||
|
||||
const service = new ConfigurationService(new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, res.testFile));
|
||||
const service = new ConfigurationService(res.testFile);
|
||||
const config = service.getValue<{
|
||||
foo: string;
|
||||
}>();
|
||||
@@ -49,7 +37,7 @@ suite('ConfigurationService - Node', () => {
|
||||
|
||||
fs.writeFileSync(res.testFile, '{ "testworkbench.editor.tabs": true }');
|
||||
|
||||
const service = new ConfigurationService(new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, res.testFile));
|
||||
const service = new ConfigurationService(res.testFile);
|
||||
const config = service.getValue<{
|
||||
testworkbench: {
|
||||
editor: {
|
||||
@@ -71,7 +59,7 @@ suite('ConfigurationService - Node', () => {
|
||||
|
||||
fs.writeFileSync(res.testFile, ',,,,');
|
||||
|
||||
const service = new ConfigurationService(new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, res.testFile));
|
||||
const service = new ConfigurationService(res.testFile);
|
||||
const config = service.getValue<{
|
||||
foo: string;
|
||||
}>();
|
||||
@@ -87,7 +75,7 @@ suite('ConfigurationService - Node', () => {
|
||||
const newDir = path.join(parentDir, 'config', id);
|
||||
const testFile = path.join(newDir, 'config.json');
|
||||
|
||||
const service = new ConfigurationService(new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, testFile));
|
||||
const service = new ConfigurationService(testFile);
|
||||
|
||||
const config = service.getValue<{ foo: string }>();
|
||||
assert.ok(config);
|
||||
@@ -98,7 +86,7 @@ suite('ConfigurationService - Node', () => {
|
||||
test('trigger configuration change event', async () => {
|
||||
const res = await testFile('config', 'config.json');
|
||||
|
||||
const service = new ConfigurationService(new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, res.testFile));
|
||||
const service = new ConfigurationService(res.testFile);
|
||||
return new Promise((c, e) => {
|
||||
service.onDidChangeConfiguration(() => {
|
||||
assert.equal(service.getValue('foo'), 'bar');
|
||||
@@ -115,7 +103,7 @@ suite('ConfigurationService - Node', () => {
|
||||
|
||||
fs.writeFileSync(res.testFile, '{ "foo": "bar" }');
|
||||
|
||||
const service = new ConfigurationService(new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, res.testFile));
|
||||
const service = new ConfigurationService(res.testFile);
|
||||
let config = service.getValue<{
|
||||
foo: string;
|
||||
}>();
|
||||
@@ -163,7 +151,7 @@ suite('ConfigurationService - Node', () => {
|
||||
}
|
||||
});
|
||||
|
||||
let serviceWithoutFile = new ConfigurationService(new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, '__testFile'));
|
||||
let serviceWithoutFile = new ConfigurationService('__testFile');
|
||||
let setting = serviceWithoutFile.getValue<ITestSetting>();
|
||||
|
||||
assert.ok(setting);
|
||||
@@ -172,7 +160,7 @@ suite('ConfigurationService - Node', () => {
|
||||
return testFile('config', 'config.json').then(async res => {
|
||||
fs.writeFileSync(res.testFile, '{ "testworkbench.editor.tabs": true }');
|
||||
|
||||
const service = new ConfigurationService(new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, res.testFile));
|
||||
const service = new ConfigurationService(res.testFile);
|
||||
|
||||
let setting = service.getValue<ITestSetting>();
|
||||
|
||||
@@ -205,7 +193,7 @@ suite('ConfigurationService - Node', () => {
|
||||
});
|
||||
|
||||
const r = await testFile('config', 'config.json');
|
||||
const service = new ConfigurationService(new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, r.testFile));
|
||||
const service = new ConfigurationService(r.testFile);
|
||||
let res = service.inspect('something.missing');
|
||||
assert.strictEqual(res.value, undefined);
|
||||
assert.strictEqual(res.default, undefined);
|
||||
@@ -241,7 +229,7 @@ suite('ConfigurationService - Node', () => {
|
||||
});
|
||||
|
||||
const r = await testFile('config', 'config.json');
|
||||
const service = new ConfigurationService(new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, r.testFile));
|
||||
const service = new ConfigurationService(r.testFile);
|
||||
let res = service.inspect('lookup.service.testNullSetting');
|
||||
assert.strictEqual(res.default, null);
|
||||
assert.strictEqual(res.value, null);
|
||||
|
||||
Reference in New Issue
Block a user