Merge from vscode 3c6f6af7347d38e87bc6406024e8dcf9e9bce229 (#8962)

* Merge from vscode 3c6f6af7347d38e87bc6406024e8dcf9e9bce229

* skip failing tests

* update mac build image
This commit is contained in:
Anthony Dresser
2020-01-27 15:28:17 -08:00
committed by Karl Burtram
parent 0eaee18dc4
commit fefe1454de
481 changed files with 12764 additions and 7836 deletions

View File

@@ -4,30 +4,87 @@
*--------------------------------------------------------------------------------------------*/
import { Disposable } from 'vs/base/common/lifecycle';
import { IFileService } from 'vs/platform/files/common/files';
import { IFileService, IFileContent } from 'vs/platform/files/common/files';
import { VSBuffer } from 'vs/base/common/buffer';
import { URI } from 'vs/base/common/uri';
import { SyncSource } from 'vs/platform/userDataSync/common/userDataSync';
import { SyncSource, SyncStatus, IUserData, IUserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSync';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { joinPath } from 'vs/base/common/resources';
import { joinPath, dirname } from 'vs/base/common/resources';
import { toLocalISOString } from 'vs/base/common/date';
import { ThrottledDelayer } from 'vs/base/common/async';
import { Emitter, Event } from 'vs/base/common/event';
export abstract class AbstractSynchroniser extends Disposable {
private readonly syncFolder: URI;
protected readonly syncFolder: URI;
private cleanUpDelayer: ThrottledDelayer<void>;
private _status: SyncStatus = SyncStatus.Idle;
get status(): SyncStatus { return this._status; }
private _onDidChangStatus: Emitter<SyncStatus> = this._register(new Emitter<SyncStatus>());
readonly onDidChangeStatus: Event<SyncStatus> = this._onDidChangStatus.event;
protected readonly _onDidChangeLocal: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChangeLocal: Event<void> = this._onDidChangeLocal.event;
protected readonly lastSyncResource: URI;
constructor(
syncSource: SyncSource,
readonly source: SyncSource,
@IFileService protected readonly fileService: IFileService,
@IEnvironmentService environmentService: IEnvironmentService
@IEnvironmentService environmentService: IEnvironmentService,
@IUserDataSyncStoreService protected readonly userDataSyncStoreService: IUserDataSyncStoreService,
) {
super();
this.syncFolder = joinPath(environmentService.userRoamingDataHome, '.sync', syncSource);
this.syncFolder = joinPath(environmentService.userDataSyncHome, source);
this.lastSyncResource = joinPath(this.syncFolder, `.lastSync${source}.json`);
this.cleanUpDelayer = new ThrottledDelayer(50);
}
protected setStatus(status: SyncStatus): void {
if (this._status !== status) {
this._status = status;
this._onDidChangStatus.fire(status);
}
}
async hasPreviouslySynced(): Promise<boolean> {
const lastSyncData = await this.getLastSyncUserData();
return !!lastSyncData;
}
async hasRemoteData(): Promise<boolean> {
const remoteUserData = await this.getRemoteUserData();
return remoteUserData.content !== null;
}
async resetLocal(): Promise<void> {
try {
await this.fileService.del(this.lastSyncResource);
} catch (e) { /* ignore */ }
}
protected async getLastSyncUserData<T extends IUserData>(): Promise<T | null> {
try {
const content = await this.fileService.readFile(this.lastSyncResource);
return JSON.parse(content.value.toString());
} catch (error) {
return null;
}
}
protected async updateLastSyncUserData<T extends IUserData>(lastSyncUserData: T): Promise<void> {
await this.fileService.writeFile(this.lastSyncResource, VSBuffer.fromString(JSON.stringify(lastSyncUserData)));
}
protected getRemoteUserData(lastSyncData?: IUserData | null): Promise<IUserData> {
return this.userDataSyncStoreService.read(this.getRemoteDataResourceKey(), lastSyncData || null, this.source);
}
protected async updateRemoteUserData(content: string, ref: string | null): Promise<string> {
return this.userDataSyncStoreService.write(this.getRemoteDataResourceKey(), content, ref, this.source);
}
protected async backupLocal(content: VSBuffer): Promise<void> {
const resource = joinPath(this.syncFolder, toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, ''));
await this.fileService.writeFile(resource, content);
@@ -43,4 +100,40 @@ export abstract class AbstractSynchroniser extends Disposable {
}
}
protected abstract getRemoteDataResourceKey(): string;
}
export abstract class AbstractFileSynchroniser extends AbstractSynchroniser {
constructor(
protected readonly file: URI,
readonly source: SyncSource,
@IFileService fileService: IFileService,
@IEnvironmentService environmentService: IEnvironmentService,
@IUserDataSyncStoreService userDataSyncStoreService: IUserDataSyncStoreService,
) {
super(source, fileService, environmentService, userDataSyncStoreService);
this._register(this.fileService.watch(dirname(file)));
this._register(Event.filter(this.fileService.onFileChanges, e => e.contains(file))(() => this._onDidChangeLocal.fire()));
}
protected async getLocalFileContent(): Promise<IFileContent | null> {
try {
return await this.fileService.readFile(this.file);
} catch (error) {
return null;
}
}
protected async updateLocalFileContent(newContent: string, oldContent: IFileContent | null): Promise<void> {
if (oldContent) {
// file exists already
await this.backupLocal(oldContent.value);
await this.fileService.writeFile(this.file, VSBuffer.fromString(newContent), oldContent);
} else {
// file does not exist
await this.fileService.createFile(this.file, VSBuffer.fromString(newContent), { overwrite: false });
}
}
}