mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge vscode source through 1.62 release (#19981)
* Build breaks 1 * Build breaks * Build breaks * Build breaks * More build breaks * Build breaks (#2512) * Runtime breaks * Build breaks * Fix dialog location break * Update typescript * Fix ASAR break issue * Unit test breaks * Update distro * Fix breaks in ADO builds (#2513) * Bump to node 16 * Fix hygiene errors * Bump distro * Remove reference to node type * Delete vscode specific extension * Bump to node 16 in CI yaml * Skip integration tests in CI builds (while fixing) * yarn.lock update * Bump moment dependency in remote yarn * Fix drop-down chevron style * Bump to node 16 * Remove playwrite from ci.yaml * Skip building build scripts in hygine check
This commit is contained in:
@@ -21,11 +21,12 @@ import { Workspace } from 'vs/platform/workspace/common/workspace';
|
||||
export class ConfigurationModel implements IConfigurationModel {
|
||||
|
||||
private isFrozen: boolean = false;
|
||||
private readonly overrideConfigurations = new Map<string, ConfigurationModel>();
|
||||
|
||||
constructor(
|
||||
private _contents: any = {},
|
||||
private _keys: string[] = [],
|
||||
private _overrides: IOverrides[] = []
|
||||
private readonly _contents: any = {},
|
||||
private readonly _keys: string[] = [],
|
||||
private readonly _overrides: IOverrides[] = []
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -66,34 +67,12 @@ export class ConfigurationModel implements IConfigurationModel {
|
||||
}
|
||||
|
||||
override(identifier: string): ConfigurationModel {
|
||||
const overrideContents = this.getContentsForOverrideIdentifer(identifier);
|
||||
|
||||
if (!overrideContents || typeof overrideContents !== 'object' || !Object.keys(overrideContents).length) {
|
||||
// If there are no valid overrides, return self
|
||||
return this;
|
||||
let overrideConfigurationModel = this.overrideConfigurations.get(identifier);
|
||||
if (!overrideConfigurationModel) {
|
||||
overrideConfigurationModel = this.createOverrideConfigurationModel(identifier);
|
||||
this.overrideConfigurations.set(identifier, overrideConfigurationModel);
|
||||
}
|
||||
|
||||
let contents: any = {};
|
||||
for (const key of arrays.distinct([...Object.keys(this.contents), ...Object.keys(overrideContents)])) {
|
||||
|
||||
let contentsForKey = this.contents[key];
|
||||
let overrideContentsForKey = overrideContents[key];
|
||||
|
||||
// If there are override contents for the key, clone and merge otherwise use base contents
|
||||
if (overrideContentsForKey) {
|
||||
// Clone and merge only if base contents and override contents are of type object otherwise just override
|
||||
if (typeof contentsForKey === 'object' && typeof overrideContentsForKey === 'object') {
|
||||
contentsForKey = objects.deepClone(contentsForKey);
|
||||
this.mergeContents(contentsForKey, overrideContentsForKey);
|
||||
} else {
|
||||
contentsForKey = overrideContentsForKey;
|
||||
}
|
||||
}
|
||||
|
||||
contents[key] = contentsForKey;
|
||||
}
|
||||
|
||||
return new ConfigurationModel(contents, this.keys, this.overrides);
|
||||
return overrideConfigurationModel;
|
||||
}
|
||||
|
||||
merge(...others: ConfigurationModel[]): ConfigurationModel {
|
||||
@@ -126,6 +105,37 @@ export class ConfigurationModel implements IConfigurationModel {
|
||||
return this;
|
||||
}
|
||||
|
||||
private createOverrideConfigurationModel(identifier: string): ConfigurationModel {
|
||||
const overrideContents = this.getContentsForOverrideIdentifer(identifier);
|
||||
|
||||
if (!overrideContents || typeof overrideContents !== 'object' || !Object.keys(overrideContents).length) {
|
||||
// If there are no valid overrides, return self
|
||||
return this;
|
||||
}
|
||||
|
||||
let contents: any = {};
|
||||
for (const key of arrays.distinct([...Object.keys(this.contents), ...Object.keys(overrideContents)])) {
|
||||
|
||||
let contentsForKey = this.contents[key];
|
||||
let overrideContentsForKey = overrideContents[key];
|
||||
|
||||
// If there are override contents for the key, clone and merge otherwise use base contents
|
||||
if (overrideContentsForKey) {
|
||||
// Clone and merge only if base contents and override contents are of type object otherwise just override
|
||||
if (typeof contentsForKey === 'object' && typeof overrideContentsForKey === 'object') {
|
||||
contentsForKey = objects.deepClone(contentsForKey);
|
||||
this.mergeContents(contentsForKey, overrideContentsForKey);
|
||||
} else {
|
||||
contentsForKey = overrideContentsForKey;
|
||||
}
|
||||
}
|
||||
|
||||
contents[key] = contentsForKey;
|
||||
}
|
||||
|
||||
return new ConfigurationModel(contents, this.keys, this.overrides);
|
||||
}
|
||||
|
||||
private mergeContents(source: any, target: any): void {
|
||||
for (const key of Object.keys(target)) {
|
||||
if (key in source) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { distinct } from 'vs/base/common/arrays';
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
@@ -37,6 +38,13 @@ export interface IConfigurationRegistry {
|
||||
*/
|
||||
deregisterConfigurations(configurations: IConfigurationNode[]): void;
|
||||
|
||||
/**
|
||||
* update the configuration registry by
|
||||
* - registering the configurations to add
|
||||
* - dereigstering the configurations to remove
|
||||
*/
|
||||
updateConfigurations(configurations: { add: IConfigurationNode[], remove: IConfigurationNode[] }): void;
|
||||
|
||||
/**
|
||||
* Register multiple default configurations to the registry.
|
||||
*/
|
||||
@@ -210,12 +218,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
||||
}
|
||||
|
||||
public registerConfigurations(configurations: IConfigurationNode[], validate: boolean = true): void {
|
||||
const properties: string[] = [];
|
||||
configurations.forEach(configuration => {
|
||||
properties.push(...this.validateAndRegisterProperties(configuration, validate, configuration.extensionInfo)); // fills in defaults
|
||||
this.configurationContributors.push(configuration);
|
||||
this.registerJSONConfiguration(configuration);
|
||||
});
|
||||
const properties = this.doRegisterConfigurations(configurations, validate);
|
||||
|
||||
contributionRegistry.registerSchema(resourceLanguageSettingsSchemaId, this.resourceLanguageSettingsSchema);
|
||||
this._onDidSchemaChange.fire();
|
||||
@@ -223,32 +226,23 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
||||
}
|
||||
|
||||
public deregisterConfigurations(configurations: IConfigurationNode[]): void {
|
||||
const properties: string[] = [];
|
||||
const deregisterConfiguration = (configuration: IConfigurationNode) => {
|
||||
if (configuration.properties) {
|
||||
for (const key in configuration.properties) {
|
||||
properties.push(key);
|
||||
delete this.configurationProperties[key];
|
||||
this.removeFromSchema(key, configuration.properties[key]);
|
||||
}
|
||||
}
|
||||
if (configuration.allOf) {
|
||||
configuration.allOf.forEach(node => deregisterConfiguration(node));
|
||||
}
|
||||
};
|
||||
for (const configuration of configurations) {
|
||||
deregisterConfiguration(configuration);
|
||||
const index = this.configurationContributors.indexOf(configuration);
|
||||
if (index !== -1) {
|
||||
this.configurationContributors.splice(index, 1);
|
||||
}
|
||||
}
|
||||
const properties = this.doDeregisterConfigurations(configurations);
|
||||
|
||||
contributionRegistry.registerSchema(resourceLanguageSettingsSchemaId, this.resourceLanguageSettingsSchema);
|
||||
this._onDidSchemaChange.fire();
|
||||
this._onDidUpdateConfiguration.fire(properties);
|
||||
}
|
||||
|
||||
public updateConfigurations({ add, remove }: { add: IConfigurationNode[], remove: IConfigurationNode[] }): void {
|
||||
const properties = [];
|
||||
properties.push(...this.doDeregisterConfigurations(remove));
|
||||
properties.push(...this.doRegisterConfigurations(add, false));
|
||||
|
||||
contributionRegistry.registerSchema(resourceLanguageSettingsSchemaId, this.resourceLanguageSettingsSchema);
|
||||
this._onDidSchemaChange.fire();
|
||||
this._onDidUpdateConfiguration.fire(distinct(properties));
|
||||
}
|
||||
|
||||
public registerDefaultConfigurations(defaultConfigurations: IStringDictionary<any>[]): void {
|
||||
const properties: string[] = [];
|
||||
const overrideIdentifiers: string[] = [];
|
||||
@@ -319,6 +313,40 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
||||
this.updateOverridePropertyPatternKey();
|
||||
}
|
||||
|
||||
private doRegisterConfigurations(configurations: IConfigurationNode[], validate: boolean): string[] {
|
||||
const properties: string[] = [];
|
||||
configurations.forEach(configuration => {
|
||||
properties.push(...this.validateAndRegisterProperties(configuration, validate, configuration.extensionInfo)); // fills in defaults
|
||||
this.configurationContributors.push(configuration);
|
||||
this.registerJSONConfiguration(configuration);
|
||||
});
|
||||
return properties;
|
||||
}
|
||||
|
||||
private doDeregisterConfigurations(configurations: IConfigurationNode[]): string[] {
|
||||
const properties: string[] = [];
|
||||
const deregisterConfiguration = (configuration: IConfigurationNode) => {
|
||||
if (configuration.properties) {
|
||||
for (const key in configuration.properties) {
|
||||
properties.push(key);
|
||||
delete this.configurationProperties[key];
|
||||
this.removeFromSchema(key, configuration.properties[key]);
|
||||
}
|
||||
}
|
||||
if (configuration.allOf) {
|
||||
configuration.allOf.forEach(node => deregisterConfiguration(node));
|
||||
}
|
||||
};
|
||||
for (const configuration of configurations) {
|
||||
deregisterConfiguration(configuration);
|
||||
const index = this.configurationContributors.indexOf(configuration);
|
||||
if (index !== -1) {
|
||||
this.configurationContributors.splice(index, 1);
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private validateAndRegisterProperties(configuration: IConfigurationNode, validate: boolean = true, extensionInfo?: IConfigurationExtensionInfo, scope: ConfigurationScope = ConfigurationScope.WINDOW): string[] {
|
||||
scope = types.isUndefinedOrNull(configuration.scope) ? scope : configuration.scope;
|
||||
let propertyKeys: string[] = [];
|
||||
|
||||
@@ -8,9 +8,8 @@ import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { JSONPath, parse, ParseError } from 'vs/base/common/json';
|
||||
import { setProperty } from 'vs/base/common/jsonEdit';
|
||||
import { Edit, FormattingOptions } from 'vs/base/common/jsonFormatter';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files';
|
||||
import { FileOperationError, FileOperationResult, IFileService, IWriteFileOptions } from 'vs/platform/files/common/files';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
@@ -31,6 +30,7 @@ export interface IUserConfigurationFileService {
|
||||
readonly _serviceBrand: undefined;
|
||||
|
||||
updateSettings(value: IJSONValue, formattingOptions: FormattingOptions): Promise<void>;
|
||||
write(value: VSBuffer, options?: IWriteFileOptions): Promise<void>;
|
||||
}
|
||||
|
||||
export class UserConfigurationFileService implements IUserConfigurationFileService {
|
||||
@@ -48,12 +48,12 @@ export class UserConfigurationFileService implements IUserConfigurationFileServi
|
||||
}
|
||||
|
||||
async updateSettings(value: IJSONValue, formattingOptions: FormattingOptions): Promise<void> {
|
||||
return this.queue.queue(() => this.doWrite(this.environmentService.settingsResource, value, formattingOptions)); // queue up writes to prevent race conditions
|
||||
return this.queue.queue(() => this.doWrite(value, formattingOptions)); // queue up writes to prevent race conditions
|
||||
}
|
||||
|
||||
private async doWrite(resource: URI, jsonValue: IJSONValue, formattingOptions: FormattingOptions): Promise<void> {
|
||||
this.logService.trace(`${UserConfigurationFileServiceId}#write`, resource.toString(), jsonValue);
|
||||
const { value, mtime, etag } = await this.fileService.readFile(resource, { atomic: true });
|
||||
private async doWrite(jsonValue: IJSONValue, formattingOptions: FormattingOptions): Promise<void> {
|
||||
this.logService.trace(`${UserConfigurationFileServiceId}#write`, this.environmentService.settingsResource.toString(), jsonValue);
|
||||
const { value, mtime, etag } = await this.fileService.readFile(this.environmentService.settingsResource, { atomic: true });
|
||||
let content = value.toString();
|
||||
|
||||
const parseErrors: ParseError[] = [];
|
||||
@@ -66,7 +66,7 @@ export class UserConfigurationFileService implements IUserConfigurationFileServi
|
||||
if (edit) {
|
||||
content = content.substring(0, edit.offset) + edit.content + content.substring(edit.offset + edit.length);
|
||||
try {
|
||||
await this.fileService.writeFile(resource, VSBuffer.fromString(content), { etag, mtime });
|
||||
await this.fileService.writeFile(this.environmentService.settingsResource, VSBuffer.fromString(content), { etag, mtime });
|
||||
} catch (error) {
|
||||
if ((<FileOperationError>error).fileOperationResult === FileOperationResult.FILE_MODIFIED_SINCE) {
|
||||
throw new Error(UserConfigurationErrorCode.ERROR_FILE_MODIFIED_SINCE);
|
||||
@@ -75,6 +75,13 @@ export class UserConfigurationFileService implements IUserConfigurationFileServi
|
||||
}
|
||||
}
|
||||
|
||||
async write(content: VSBuffer, options?: IWriteFileOptions): Promise<void> {
|
||||
// queue up writes to prevent race conditions
|
||||
return this.queue.queue(async () => {
|
||||
await this.fileService.writeFile(this.environmentService.settingsResource, content, options);
|
||||
});
|
||||
}
|
||||
|
||||
private getEdits({ value, path }: IJSONValue, modelContent: string, formattingOptions: FormattingOptions): Edit[] {
|
||||
if (path.length) {
|
||||
return setProperty(modelContent, path, value, formattingOptions);
|
||||
|
||||
@@ -89,12 +89,12 @@ suite('ConfigurationService', () => {
|
||||
test('trigger configuration change event when file does not exist', async () => {
|
||||
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService));
|
||||
await testObject.initialize();
|
||||
return new Promise<void>(async (c) => {
|
||||
return new Promise<void>((c, e) => {
|
||||
disposables.add(Event.filter(testObject.onDidChangeConfiguration, e => e.source === ConfigurationTarget.USER)(() => {
|
||||
assert.strictEqual(testObject.getValue('foo'), 'bar');
|
||||
c();
|
||||
}));
|
||||
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }'));
|
||||
fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }')).catch(e);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -34,7 +34,7 @@ export class TestConfigurationService implements IConfigurationService {
|
||||
}
|
||||
configuration = configuration ? configuration : this.configuration;
|
||||
if (arg1 && typeof arg1 === 'string') {
|
||||
return getConfigurationValue(configuration, arg1);
|
||||
return configuration[arg1] ?? getConfigurationValue(configuration, arg1);
|
||||
}
|
||||
return configuration;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user