Merge from vscode a234f13c45b40a0929777cb440ee011b7549eed2 (#8911)

* Merge from vscode a234f13c45b40a0929777cb440ee011b7549eed2

* update distro

* fix layering

* update distro

* fix tests
This commit is contained in:
Anthony Dresser
2020-01-22 13:42:37 -08:00
committed by GitHub
parent 977111eb21
commit bd7aac8ee0
895 changed files with 24651 additions and 14520 deletions

View File

@@ -3,15 +3,16 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IUserDataSyncService, SyncStatus, ISynchroniser, IUserDataSyncStoreService, SyncSource } from 'vs/platform/userDataSync/common/userDataSync';
import { IUserDataSyncService, SyncStatus, ISynchroniser, IUserDataSyncStoreService, SyncSource, ISettingsSyncService, IUserDataSyncLogService, IUserDataAuthTokenService } from 'vs/platform/userDataSync/common/userDataSync';
import { Disposable } from 'vs/base/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { SettingsSynchroniser } from 'vs/platform/userDataSync/common/settingsSync';
import { Emitter, Event } from 'vs/base/common/event';
import { ExtensionsSynchroniser } from 'vs/platform/userDataSync/common/extensionsSync';
import { IExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { IAuthTokenService, AuthTokenStatus } from 'vs/platform/auth/common/auth';
import { KeybindingsSynchroniser } from 'vs/platform/userDataSync/common/keybindingsSync';
import { GlobalStateSynchroniser } from 'vs/platform/userDataSync/common/globalStateSync';
import { toErrorMessage } from 'vs/base/common/errorMessage';
export class UserDataSyncService extends Disposable implements IUserDataSyncService {
@@ -29,39 +30,78 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
private _conflictsSource: SyncSource | null = null;
get conflictsSource(): SyncSource | null { return this._conflictsSource; }
private readonly settingsSynchroniser: SettingsSynchroniser;
private readonly keybindingsSynchroniser: KeybindingsSynchroniser;
private readonly extensionsSynchroniser: ExtensionsSynchroniser;
private readonly globalStateSynchroniser: GlobalStateSynchroniser;
constructor(
@IUserDataSyncStoreService private readonly userDataSyncStoreService: IUserDataSyncStoreService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IAuthTokenService private readonly authTokenService: IAuthTokenService,
@ISettingsSyncService private readonly settingsSynchroniser: ISettingsSyncService,
@IUserDataSyncLogService private readonly logService: IUserDataSyncLogService,
@IUserDataAuthTokenService private readonly userDataAuthTokenService: IUserDataAuthTokenService,
) {
super();
this.settingsSynchroniser = this._register(this.instantiationService.createInstance(SettingsSynchroniser));
this.keybindingsSynchroniser = this._register(this.instantiationService.createInstance(KeybindingsSynchroniser));
this.globalStateSynchroniser = this._register(this.instantiationService.createInstance(GlobalStateSynchroniser));
this.extensionsSynchroniser = this._register(this.instantiationService.createInstance(ExtensionsSynchroniser));
this.synchronisers = [this.settingsSynchroniser, this.keybindingsSynchroniser, this.extensionsSynchroniser];
this.synchronisers = [this.settingsSynchroniser, this.keybindingsSynchroniser, this.globalStateSynchroniser, this.extensionsSynchroniser];
this.updateStatus();
if (this.userDataSyncStoreService.userDataSyncStore) {
this._register(Event.any(...this.synchronisers.map(s => Event.map(s.onDidChangeStatus, () => undefined)))(() => this.updateStatus()));
this._register(this.userDataAuthTokenService.onDidChangeToken(e => this.onDidChangeAuthTokenStatus(e)));
}
this.onDidChangeLocal = Event.any(...this.synchronisers.map(s => s.onDidChangeLocal));
}
async pull(): Promise<void> {
if (!this.userDataSyncStoreService.userDataSyncStore) {
throw new Error('Not enabled');
}
if (!(await this.userDataAuthTokenService.getToken())) {
throw new Error('Not Authenticated. Please sign in to start sync.');
}
for (const synchroniser of this.synchronisers) {
try {
await synchroniser.pull();
} catch (e) {
this.logService.error(`${this.getSyncSource(synchroniser)}: ${toErrorMessage(e)}`);
}
}
}
async push(): Promise<void> {
if (!this.userDataSyncStoreService.userDataSyncStore) {
throw new Error('Not enabled');
}
if (!(await this.userDataAuthTokenService.getToken())) {
throw new Error('Not Authenticated. Please sign in to start sync.');
}
for (const synchroniser of this.synchronisers) {
try {
await synchroniser.push();
} catch (e) {
this.logService.error(`${this.getSyncSource(synchroniser)}: ${toErrorMessage(e)}`);
}
}
}
async sync(_continue?: boolean): Promise<boolean> {
if (!this.userDataSyncStoreService.userDataSyncStore) {
throw new Error('Not enabled');
}
if (this.authTokenService.status === AuthTokenStatus.SignedOut) {
if (!(await this.userDataAuthTokenService.getToken())) {
throw new Error('Not Authenticated. Please sign in to start sync.');
}
for (const synchroniser of this.synchronisers) {
if (!await synchroniser.sync(_continue)) {
return false;
try {
if (!await synchroniser.sync(_continue)) {
return false;
}
} catch (e) {
this.logService.error(`${this.getSyncSource(synchroniser)}: ${toErrorMessage(e)}`);
}
}
return true;
@@ -76,6 +116,101 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
}
}
async hasPreviouslySynced(): Promise<boolean> {
if (!this.userDataSyncStoreService.userDataSyncStore) {
throw new Error('Not enabled');
}
if (!(await this.userDataAuthTokenService.getToken())) {
throw new Error('Not Authenticated. Please sign in to start sync.');
}
for (const synchroniser of this.synchronisers) {
if (await synchroniser.hasPreviouslySynced()) {
return true;
}
}
return false;
}
async hasRemoteData(): Promise<boolean> {
if (!this.userDataSyncStoreService.userDataSyncStore) {
throw new Error('Not enabled');
}
if (!(await this.userDataAuthTokenService.getToken())) {
throw new Error('Not Authenticated. Please sign in to start sync.');
}
for (const synchroniser of this.synchronisers) {
if (await synchroniser.hasRemoteData()) {
return true;
}
}
return false;
}
async hasLocalData(): Promise<boolean> {
if (!this.userDataSyncStoreService.userDataSyncStore) {
throw new Error('Not enabled');
}
if (!(await this.userDataAuthTokenService.getToken())) {
throw new Error('Not Authenticated. Please sign in to start sync.');
}
for (const synchroniser of this.synchronisers) {
if (await synchroniser.hasLocalData()) {
return true;
}
}
return false;
}
async isFirstTimeSyncAndHasUserData(): Promise<boolean> {
if (!this.userDataSyncStoreService.userDataSyncStore) {
throw new Error('Not enabled');
}
if (!(await this.userDataAuthTokenService.getToken())) {
throw new Error('Not Authenticated. Please sign in to start sync.');
}
if (await this.hasPreviouslySynced()) {
return false;
}
return await this.hasLocalData();
}
async reset(): Promise<void> {
await this.resetRemote();
await this.resetLocal();
}
private async resetRemote(): Promise<void> {
if (!this.userDataSyncStoreService.userDataSyncStore) {
throw new Error('Not enabled');
}
if (!(await this.userDataAuthTokenService.getToken())) {
throw new Error('Not Authenticated. Please sign in to start sync.');
}
try {
await this.userDataSyncStoreService.clear();
this.logService.info('Completed clearing remote data');
} catch (e) {
this.logService.error(e);
}
}
async resetLocal(): Promise<void> {
if (!this.userDataSyncStoreService.userDataSyncStore) {
throw new Error('Not enabled');
}
if (!(await this.userDataAuthTokenService.getToken())) {
throw new Error('Not Authenticated. Please sign in to start sync.');
}
for (const synchroniser of this.synchronisers) {
try {
await synchroniser.resetLocal();
} catch (e) {
this.logService.error(`${this.getSyncSource(synchroniser)}: ${toErrorMessage(e)}`);
}
}
this.logService.info('Completed resetting local cache');
}
removeExtension(identifier: IExtensionIdentifier): Promise<void> {
return this.extensionsSynchroniser.removeExtension(identifier);
}
@@ -106,15 +241,26 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
}
private computeConflictsSource(): SyncSource | null {
const source = this.synchronisers.filter(s => s.status === SyncStatus.HasConflicts)[0];
if (source) {
if (source instanceof SettingsSynchroniser) {
return SyncSource.Settings;
}
if (source instanceof KeybindingsSynchroniser) {
return SyncSource.Keybindings;
}
const synchroniser = this.synchronisers.filter(s => s.status === SyncStatus.HasConflicts)[0];
return synchroniser ? this.getSyncSource(synchroniser) : null;
}
private getSyncSource(synchroniser: ISynchroniser): SyncSource {
if (synchroniser instanceof SettingsSynchroniser) {
return SyncSource.Settings;
}
if (synchroniser instanceof KeybindingsSynchroniser) {
return SyncSource.Keybindings;
}
if (synchroniser instanceof ExtensionsSynchroniser) {
return SyncSource.Extensions;
}
return SyncSource.UIState;
}
private onDidChangeAuthTokenStatus(token: string | undefined): void {
if (!token) {
this.stop();
}
return null;
}
}