mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 27ada910e121e23a6d95ecca9cae595fb98ab568
This commit is contained in:
@@ -98,8 +98,13 @@ export function merge(originalLocalContent: string, originalRemoteContent: strin
|
||||
return { conflictsSettings: [], localContent: updateIgnoredSettings(originalRemoteContent, originalLocalContent, ignoredSettings, formattingOptions), remoteContent: null, hasConflicts: false };
|
||||
}
|
||||
|
||||
/* remote and local has changed */
|
||||
/* local is empty and not synced before */
|
||||
if (baseContent === null && isEmpty(originalLocalContent)) {
|
||||
const localContent = areSame(originalLocalContent, originalRemoteContent, ignoredSettings) ? null : updateIgnoredSettings(originalRemoteContent, originalLocalContent, ignoredSettings, formattingOptions);
|
||||
return { conflictsSettings: [], localContent, remoteContent: null, hasConflicts: false };
|
||||
}
|
||||
|
||||
/* remote and local has changed */
|
||||
let localContent = originalLocalContent;
|
||||
let remoteContent = originalRemoteContent;
|
||||
const local = parse(originalLocalContent);
|
||||
@@ -258,6 +263,11 @@ export function areSame(localContent: string, remoteContent: string, ignoredSett
|
||||
return true;
|
||||
}
|
||||
|
||||
export function isEmpty(content: string): boolean {
|
||||
const nodes = parseSettings(content);
|
||||
return nodes.length === 0;
|
||||
}
|
||||
|
||||
function compare(from: IStringDictionary<any> | null, to: IStringDictionary<any>, ignored: Set<string>): { added: Set<string>, removed: Set<string>, updated: Set<string> } {
|
||||
const fromKeys = from ? Object.keys(from).filter(key => !ignored.has(key)) : [];
|
||||
const toKeys = Object.keys(to).filter(key => !ignored.has(key));
|
||||
|
||||
@@ -6,15 +6,13 @@
|
||||
import { IFileService, FileOperationError, FileOperationResult } from 'vs/platform/files/common/files';
|
||||
import { UserDataSyncError, UserDataSyncErrorCode, SyncStatus, IUserDataSyncStoreService, IUserDataSyncLogService, IUserDataSyncUtilService, CONFIGURATION_SYNC_STORE_KEY, SyncResource, IUserDataSyncEnablementService, IUserDataSyncBackupStoreService, USER_DATA_SYNC_SCHEME, PREVIEW_DIR_NAME, ISyncResourceHandle } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { parse } from 'vs/base/common/json';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { createCancelablePromise } from 'vs/base/common/async';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { updateIgnoredSettings, merge, getIgnoredSettings } from 'vs/platform/userDataSync/common/settingsMerge';
|
||||
import { isEmptyObject } from 'vs/base/common/types';
|
||||
import { updateIgnoredSettings, merge, getIgnoredSettings, isEmpty } from 'vs/platform/userDataSync/common/settingsMerge';
|
||||
import { edit } from 'vs/platform/userDataSync/common/content';
|
||||
import { IFileSyncPreviewResult, AbstractJsonFileSynchroniser, IRemoteUserData } from 'vs/platform/userDataSync/common/abstractSynchronizer';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
@@ -160,10 +158,7 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser {
|
||||
if (localFileContent) {
|
||||
const formatUtils = await this.getFormattingOptions();
|
||||
const content = edit(localFileContent.value.toString(), [CONFIGURATION_SYNC_STORE_KEY], undefined, formatUtils);
|
||||
const settings = parse(content);
|
||||
if (!isEmptyObject(settings)) {
|
||||
return true;
|
||||
}
|
||||
return !isEmpty(content);
|
||||
}
|
||||
} catch (error) {
|
||||
if ((<FileOperationError>error).fileOperationResult !== FileOperationResult.FILE_NOT_FOUND) {
|
||||
|
||||
@@ -417,7 +417,7 @@ export class SnippetsSynchroniser extends AbstractSynchroniser implements IUserD
|
||||
for (const entry of stat.children || []) {
|
||||
const resource = entry.resource;
|
||||
const extension = extname(resource);
|
||||
if (extension === '.json' || extension === '.code-snippet') {
|
||||
if (extension === '.json' || extension === '.code-snippets') {
|
||||
const key = relativePath(this.snippetsFolder, resource)!;
|
||||
const content = await this.fileService.readFile(resource);
|
||||
snippets[key] = content;
|
||||
|
||||
@@ -42,7 +42,7 @@ export class UserDataAutoSyncService extends Disposable implements IUserDataAuto
|
||||
}
|
||||
|
||||
private async updateEnablement(stopIfDisabled: boolean, auto: boolean): Promise<void> {
|
||||
const enabled = await this.isAutoSyncEnabled();
|
||||
const { enabled, reason } = await this.isAutoSyncEnabled();
|
||||
if (this.enabled === enabled) {
|
||||
return;
|
||||
}
|
||||
@@ -56,7 +56,7 @@ export class UserDataAutoSyncService extends Disposable implements IUserDataAuto
|
||||
this.resetFailures();
|
||||
if (stopIfDisabled) {
|
||||
this.userDataSyncService.stop();
|
||||
this.logService.info('Auto Sync: stopped.');
|
||||
this.logService.info('Auto Sync: stopped because', reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,10 +95,18 @@ export class UserDataAutoSyncService extends Disposable implements IUserDataAuto
|
||||
}
|
||||
}
|
||||
|
||||
private async isAutoSyncEnabled(): Promise<boolean> {
|
||||
return this.userDataSyncEnablementService.isEnabled()
|
||||
&& this.userDataSyncService.status !== SyncStatus.Uninitialized
|
||||
&& !!(await this.authTokenService.getToken());
|
||||
private async isAutoSyncEnabled(): Promise<{ enabled: boolean, reason?: string }> {
|
||||
if (!this.userDataSyncEnablementService.isEnabled()) {
|
||||
return { enabled: false, reason: 'sync is disabled' };
|
||||
}
|
||||
if (this.userDataSyncService.status === SyncStatus.Uninitialized) {
|
||||
return { enabled: false, reason: 'sync is not initialized' };
|
||||
}
|
||||
const token = await this.authTokenService.getToken();
|
||||
if (!token) {
|
||||
return { enabled: false, reason: 'token is not avaialable' };
|
||||
}
|
||||
return { enabled: true };
|
||||
}
|
||||
|
||||
private resetFailures(): void {
|
||||
|
||||
@@ -26,19 +26,6 @@ import { isArray, isString, isObject } from 'vs/base/common/types';
|
||||
|
||||
export const CONFIGURATION_SYNC_STORE_KEY = 'configurationSync.store';
|
||||
|
||||
export interface ISyncConfiguration {
|
||||
sync: {
|
||||
enable: boolean,
|
||||
enableSettings: boolean,
|
||||
enableKeybindings: boolean,
|
||||
enableUIState: boolean,
|
||||
enableExtensions: boolean,
|
||||
keybindingsPerPlatform: boolean,
|
||||
ignoredExtensions: string[],
|
||||
ignoredSettings: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export function getDisallowedIgnoredSettings(): string[] {
|
||||
const allSettings = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).getConfigurationProperties();
|
||||
return Object.keys(allSettings).filter(setting => !!allSettings[setting].disallowSyncIgnore);
|
||||
|
||||
@@ -723,6 +723,23 @@ suite('SettingsMerge - Merge', () => {
|
||||
assert.deepEqual(actual.conflictsSettings, expectedConflicts);
|
||||
assert.ok(actual.hasConflicts);
|
||||
});
|
||||
|
||||
test('merge when remote has comments and local is empty', async () => {
|
||||
const localContent = `
|
||||
{
|
||||
|
||||
}`;
|
||||
const remoteContent = stringify`
|
||||
{
|
||||
// this is a comment
|
||||
"a": 1,
|
||||
}`;
|
||||
const actual = merge(localContent, remoteContent, null, [], [], formattingOptions);
|
||||
assert.equal(actual.localContent, remoteContent);
|
||||
assert.equal(actual.remoteContent, null);
|
||||
assert.equal(actual.conflictsSettings.length, 0);
|
||||
assert.ok(!actual.hasConflicts);
|
||||
});
|
||||
});
|
||||
|
||||
suite('SettingsMerge - Compute Remote Content', () => {
|
||||
|
||||
@@ -597,7 +597,7 @@ suite('SnippetsSync', () => {
|
||||
});
|
||||
|
||||
test('sync global and language snippet', async () => {
|
||||
await updateSnippet('global.code-snippet', globalSnippet, client2);
|
||||
await updateSnippet('global.code-snippets', globalSnippet, client2);
|
||||
await updateSnippet('html.json', htmlSnippet1, client2);
|
||||
await client2.sync();
|
||||
|
||||
@@ -607,17 +607,17 @@ suite('SnippetsSync', () => {
|
||||
|
||||
const actual1 = await readSnippet('html.json', testClient);
|
||||
assert.equal(actual1, htmlSnippet1);
|
||||
const actual2 = await readSnippet('global.code-snippet', testClient);
|
||||
const actual2 = await readSnippet('global.code-snippets', testClient);
|
||||
assert.equal(actual2, globalSnippet);
|
||||
|
||||
const { content } = await testClient.read(testObject.resource);
|
||||
assert.ok(content !== null);
|
||||
const actual = parseSnippets(content!);
|
||||
assert.deepEqual(actual, { 'html.json': htmlSnippet1, 'global.code-snippet': globalSnippet });
|
||||
assert.deepEqual(actual, { 'html.json': htmlSnippet1, 'global.code-snippets': globalSnippet });
|
||||
});
|
||||
|
||||
test('sync should ignore non snippets', async () => {
|
||||
await updateSnippet('global.code-snippet', globalSnippet, client2);
|
||||
await updateSnippet('global.code-snippets', globalSnippet, client2);
|
||||
await updateSnippet('html.html', htmlSnippet1, client2);
|
||||
await updateSnippet('typescript.json', tsSnippet1, client2);
|
||||
await client2.sync();
|
||||
@@ -628,7 +628,7 @@ suite('SnippetsSync', () => {
|
||||
|
||||
const actual1 = await readSnippet('typescript.json', testClient);
|
||||
assert.equal(actual1, tsSnippet1);
|
||||
const actual2 = await readSnippet('global.code-snippet', testClient);
|
||||
const actual2 = await readSnippet('global.code-snippets', testClient);
|
||||
assert.equal(actual2, globalSnippet);
|
||||
const actual3 = await readSnippet('html.html', testClient);
|
||||
assert.equal(actual3, null);
|
||||
@@ -636,7 +636,7 @@ suite('SnippetsSync', () => {
|
||||
const { content } = await testClient.read(testObject.resource);
|
||||
assert.ok(content !== null);
|
||||
const actual = parseSnippets(content!);
|
||||
assert.deepEqual(actual, { 'typescript.json': tsSnippet1, 'global.code-snippet': globalSnippet });
|
||||
assert.deepEqual(actual, { 'typescript.json': tsSnippet1, 'global.code-snippets': globalSnippet });
|
||||
});
|
||||
|
||||
function parseSnippets(content: string): IStringDictionary<string> {
|
||||
|
||||
Reference in New Issue
Block a user