From 08d40c8f0ee6b6539216e0bc21496975a6809174 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 25 Sep 2019 19:14:42 +0200 Subject: [PATCH] ignore settings and extensions --- .../userDataSync/common/extensionsSync.ts | 22 ++++++++------- .../userDataSync/common/settingsSync.ts | 26 ++++++++++++------ .../userDataSync/common/userDataSync.ts | 27 ++++++++++++------- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/vs/platform/userDataSync/common/extensionsSync.ts b/src/vs/platform/userDataSync/common/extensionsSync.ts index 4d507e6dc5e..b05d1d9f032 100644 --- a/src/vs/platform/userDataSync/common/extensionsSync.ts +++ b/src/vs/platform/userDataSync/common/extensionsSync.ts @@ -144,10 +144,10 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser * - Update remote with those local extension which are newly added or updated or removed and untouched in remote. */ private merge(localExtensions: ISyncExtension[], remoteExtensions: ISyncExtension[] | null, lastSyncExtensions: ISyncExtension[] | null): { added: ISyncExtension[], removed: IExtensionIdentifier[], updated: ISyncExtension[], remote: ISyncExtension[] | null } { - + const ignoredExtensions = this.configurationService.getValue('userConfiguration.ignoredExtensions') || []; // First time sync if (!remoteExtensions) { - return { added: [], removed: [], updated: [], remote: localExtensions }; + return { added: [], removed: [], updated: [], remote: localExtensions.filter(({ identifier }) => ignoredExtensions.some(id => id.toLowerCase() === identifier.id.toLowerCase())) }; } const uuids: Map = new Map(); @@ -168,8 +168,12 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser const remoteExtensionsMap = remoteExtensions.reduce(addExtensionToMap, new Map()); const newRemoteExtensionsMap = remoteExtensions.reduce(addExtensionToMap, new Map()); const lastSyncExtensionsMap = lastSyncExtensions ? lastSyncExtensions.reduce(addExtensionToMap, new Map()) : null; + const ignoredExtensionsSet = ignoredExtensions.reduce((set, id) => { + const uuid = uuids.get(id.toLowerCase()); + return set.add(uuid ? `uuid:${uuid}` : `id:${id.toLowerCase()}`); + }, new Set()); - const localToRemote = this.compare(localExtensionsMap, remoteExtensionsMap); + const localToRemote = this.compare(localExtensionsMap, remoteExtensionsMap, ignoredExtensionsSet); if (localToRemote.added.size === 0 && localToRemote.removed.size === 0 && localToRemote.updated.size === 0) { // No changes found between local and remote. return { added: [], removed: [], updated: [], remote: null }; @@ -179,8 +183,8 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser const removed: IExtensionIdentifier[] = []; const updated: ISyncExtension[] = []; - const baseToLocal = lastSyncExtensionsMap ? this.compare(lastSyncExtensionsMap, localExtensionsMap) : { added: keys(localExtensionsMap).reduce((r, k) => { r.add(k); return r; }, new Set()), removed: new Set(), updated: new Set() }; - const baseToRemote = lastSyncExtensionsMap ? this.compare(lastSyncExtensionsMap, remoteExtensionsMap) : { added: keys(remoteExtensionsMap).reduce((r, k) => { r.add(k); return r; }, new Set()), removed: new Set(), updated: new Set() }; + const baseToLocal = lastSyncExtensionsMap ? this.compare(lastSyncExtensionsMap, localExtensionsMap, ignoredExtensionsSet) : { added: keys(localExtensionsMap).reduce((r, k) => { r.add(k); return r; }, new Set()), removed: new Set(), updated: new Set() }; + const baseToRemote = lastSyncExtensionsMap ? this.compare(lastSyncExtensionsMap, remoteExtensionsMap, ignoredExtensionsSet) : { added: keys(remoteExtensionsMap).reduce((r, k) => { r.add(k); return r; }, new Set()), removed: new Set(), updated: new Set() }; const massageSyncExtension = (extension: ISyncExtension, key: string): ISyncExtension => { return { @@ -256,14 +260,14 @@ export class ExtensionsSynchroniser extends Disposable implements ISynchroniser } } - const remoteChanges = this.compare(remoteExtensionsMap, newRemoteExtensionsMap); + const remoteChanges = this.compare(remoteExtensionsMap, newRemoteExtensionsMap, new Set()); const remote = remoteChanges.added.size > 0 || remoteChanges.updated.size > 0 || remoteChanges.removed.size > 0 ? values(newRemoteExtensionsMap) : null; return { added, removed, updated, remote }; } - private compare(from: Map, to: Map): { added: Set, removed: Set, updated: Set } { - const fromKeys = keys(from); - const toKeys = keys(to); + private compare(from: Map, to: Map, ignoredExtensions: Set): { added: Set, removed: Set, updated: Set } { + const fromKeys = keys(from).filter(key => !ignoredExtensions.has(key)); + const toKeys = keys(to).filter(key => !ignoredExtensions.has(key)); const added = toKeys.filter(key => fromKeys.indexOf(key) === -1).reduce((r, key) => { r.add(key); return r; }, new Set()); const removed = fromKeys.filter(key => toKeys.indexOf(key) === -1).reduce((r, key) => { r.add(key); return r; }, new Set()); const updated: Set = new Set(); diff --git a/src/vs/platform/userDataSync/common/settingsSync.ts b/src/vs/platform/userDataSync/common/settingsSync.ts index 82f1fbad08a..de939c2c7e2 100644 --- a/src/vs/platform/userDataSync/common/settingsSync.ts +++ b/src/vs/platform/userDataSync/common/settingsSync.ts @@ -5,7 +5,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IFileService, FileSystemProviderErrorCode, FileSystemProviderError, IFileContent } from 'vs/platform/files/common/files'; -import { IUserData, UserDataSyncStoreError, UserDataSyncStoreErrorCode, ISynchroniser, SyncStatus, ISettingsMergeService, IUserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSync'; +import { IUserData, UserDataSyncStoreError, UserDataSyncStoreErrorCode, ISynchroniser, SyncStatus, ISettingsMergeService, IUserDataSyncStoreService, DEFAULT_IGNORED_SETTINGS } from 'vs/platform/userDataSync/common/userDataSync'; import { VSBuffer } from 'vs/base/common/buffer'; import { parse, ParseError } from 'vs/base/common/json'; import { localize } from 'vs/nls'; @@ -16,6 +16,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { URI } from 'vs/base/common/uri'; import { joinPath } from 'vs/base/common/resources'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { startsWith } from 'vs/base/common/strings'; interface ISyncPreviewResult { readonly fileContent: IFileContent | null; @@ -139,14 +140,14 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser { } let { fileContent, remoteUserData, hasLocalChanged, hasRemoteChanged } = await this.syncPreviewResultPromise; + if (hasLocalChanged) { + await this.writeToLocal(content, fileContent); + } if (hasRemoteChanged) { - const remoteContent = remoteUserData.content ? await this.settingsMergeService.computeRemoteContent(content, remoteUserData.content, this.getIgnoredSettings()) : content; + const remoteContent = remoteUserData.content ? await this.settingsMergeService.computeRemoteContent(content, remoteUserData.content, this.getIgnoredSettings(content)) : content; const ref = await this.writeToRemote(remoteContent, remoteUserData.ref); remoteUserData = { ref, content }; } - if (hasLocalChanged) { - await this.writeToLocal(content, fileContent); - } if (remoteUserData.content) { await this.updateLastSyncValue(remoteUserData); } @@ -188,7 +189,7 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser { || lastSyncData.content !== localContent // Local has moved forwarded || lastSyncData.content !== remoteContent // Remote has moved forwarded ) { - this.logService.trace('Settings Sync: Merging remote contents with settings file.'); + this.logService.info('Settings Sync: Merging remote contents with settings file.'); const result = await this.settingsMergeService.merge(localContent, remoteContent, lastSyncData ? lastSyncData.content : null, this.getIgnoredSettings()); // Sync only if there are changes if (result.hasChanges) { @@ -212,8 +213,17 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser { return { fileContent, remoteUserData, hasLocalChanged, hasRemoteChanged, hasConflicts }; } - private getIgnoredSettings(): string[] { - return this.configurationService.getValue('userConfiguration.ignoreSettings'); + private getIgnoredSettings(settingsContent?: string): string[] { + const value: string[] = (settingsContent ? parse(settingsContent)['userConfiguration.ignoredSettings'] : this.configurationService.getValue('userConfiguration.ignoredSettings')) || []; + const added: string[] = [], removed: string[] = []; + for (const key of value) { + if (startsWith(key, '-')) { + removed.push(key.substring(1)); + } else { + added.push(key); + } + } + return [...DEFAULT_IGNORED_SETTINGS, ...added].filter(setting => removed.indexOf(setting) === -1); } private async getLastSyncUserData(): Promise { diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index 9c480b45ebe..c65b795d758 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -14,6 +14,12 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; +export const DEFAULT_IGNORED_SETTINGS = [ + 'userConfiguration.enableSync', + 'userConfiguration.syncSettings', + 'userConfiguration.syncExtensions', +]; + export function registerConfiguration(): IDisposable { const ignoredSettingsSchemaId = 'vscode://schemas/ignoredSettings'; const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); @@ -41,19 +47,20 @@ export function registerConfiguration(): IDisposable { default: true, scope: ConfigurationScope.APPLICATION, }, - 'userConfiguration.ignoreSettings': { + 'userConfiguration.ignoredExtensions': { + 'type': 'array', + description: localize('userConfiguration.ignoredExtensions', "Configure extensions which will be ignored while syncing."), + 'default': [], + 'scope': ConfigurationScope.APPLICATION, + uniqueItems: true + }, + 'userConfiguration.ignoredSettings': { 'type': 'array', - description: localize('userConfiguration.ignoreSettings', "Configure settings to be ignored while syncing"), - 'default': [ - 'userConfiguration.enableSync', - 'userConfiguration.syncExtensions', - 'userConfiguration.ignoreSettings' - ], + description: localize('userConfiguration.ignoredSettings', "Configure settings which will be ignored while syncing. \nDefault Ignored Settings:\n\n{0}", DEFAULT_IGNORED_SETTINGS.sort().map(setting => `- ${setting}`).join('\n')), + 'default': [], 'scope': ConfigurationScope.APPLICATION, $ref: ignoredSettingsSchemaId, additionalProperties: true, - allowTrailingCommas: true, - allowComments: true, uniqueItems: true } } @@ -63,7 +70,7 @@ export function registerConfiguration(): IDisposable { const ignoredSettingsSchema: IJSONSchema = { items: { type: 'string', - enum: Object.keys(allSettings.properties) + enum: [...Object.keys(allSettings.properties).filter(setting => DEFAULT_IGNORED_SETTINGS.indexOf(setting) === -1), ...DEFAULT_IGNORED_SETTINGS.map(setting => `-${setting}`)] } }; jsonRegistry.registerSchema(ignoredSettingsSchemaId, ignoredSettingsSchema); -- GitLab