Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* Fix #162439

* better fix and also add tests
  • Loading branch information
sandy081 authored Oct 26, 2022
1 parent 002db8f commit 942cc4b
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 8 deletions.
10 changes: 10 additions & 0 deletions src/vs/platform/userDataSync/common/abstractSynchronizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,16 @@ export abstract class AbstractFileSynchroniser extends AbstractSynchroniser {
}
}

protected async deleteLocalFile(): Promise<void> {
try {
await this.fileService.del(this.file);
} catch (e) {
if (!(e instanceof FileOperationError && e.fileOperationResult === FileOperationResult.FILE_NOT_FOUND)) {
throw e;
}
}
}

private onFileChanges(e: FileChangesEvent): void {
if (!e.contains(this.file)) {
return;
Expand Down
18 changes: 11 additions & 7 deletions src/vs/platform/userDataSync/common/tasksSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { AbstractFileSynchroniser, AbstractInitializer, IAcceptResult, IFileReso
import { Change, IRemoteUserData, IUserDataSyncBackupStoreService, IUserDataSyncConfiguration, IUserDataSynchroniser, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncStoreService, SyncResource, USER_DATA_SYNC_SCHEME } from 'vs/platform/userDataSync/common/userDataSync';

interface ITasksSyncContent {
tasks: string;
tasks?: string;
}

interface ITasksResourcePreview extends IFileResourcePreview {
Expand All @@ -28,7 +28,7 @@ interface ITasksResourcePreview extends IFileResourcePreview {
export function getTasksContentFromSyncContent(syncContent: string, logService: ILogService): string | null {
try {
const parsed = <ITasksSyncContent>JSON.parse(syncContent);
return parsed.tasks;
return parsed.tasks ?? null;
} catch (e) {
logService.error(e);
return null;
Expand Down Expand Up @@ -76,7 +76,7 @@ export class TasksSynchroniser extends AbstractFileSynchroniser implements IUser
let hasRemoteChanged: boolean = false;
let hasConflicts: boolean = false;

if (remoteContent) {
if (remoteUserData.syncData) {
const localContent = fileContent ? fileContent.value.toString() : null;
if (!lastSyncContent // First time sync
|| lastSyncContent !== localContent // Local has forwarded
Expand Down Expand Up @@ -196,13 +196,17 @@ export class TasksSynchroniser extends AbstractFileSynchroniser implements IUser
if (fileContent) {
await this.backupLocal(JSON.stringify(this.toTasksSyncContent(fileContent.value.toString())));
}
await this.updateLocalFileContent(content || '{}', fileContent, force);
if (content) {
await this.updateLocalFileContent(content, fileContent, force);
} else {
await this.deleteLocalFile();
}
this.logService.info(`${this.syncResourceLogLabel}: Updated local tasks`);
}

if (remoteChange !== Change.None) {
this.logService.trace(`${this.syncResourceLogLabel}: Updating remote tasks...`);
const remoteContents = JSON.stringify(this.toTasksSyncContent(content || '{}'));
const remoteContents = JSON.stringify(this.toTasksSyncContent(content));
remoteUserData = await this.updateRemoteUserData(remoteContents, force ? null : remoteUserData.ref);
this.logService.info(`${this.syncResourceLogLabel}: Updated remote tasks`);
}
Expand Down Expand Up @@ -235,8 +239,8 @@ export class TasksSynchroniser extends AbstractFileSynchroniser implements IUser
return null;
}

private toTasksSyncContent(tasks: string): ITasksSyncContent {
return { tasks };
private toTasksSyncContent(tasks: string | null): ITasksSyncContent {
return tasks ? { tasks } : {};
}

}
Expand Down
30 changes: 29 additions & 1 deletion src/vs/platform/userDataSync/test/common/tasksSync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,34 @@ suite('TasksSync', () => {
assert.strictEqual((await fileService.readFile(tasksResource)).value.toString(), content);
});

test('when tasks file was removed in one client', async () => {
const fileService = client.instantiationService.get(IFileService);
const tasksResource = client.instantiationService.get(IUserDataProfilesService).defaultProfile.tasksResource;
await fileService.writeFile(tasksResource, VSBuffer.fromString(JSON.stringify({
'version': '2.0.0',
'tasks': []
})));
await testObject.sync(await client.getResourceManifest());

const client2 = disposableStore.add(new UserDataSyncClient(server));
await client2.setUp(true);
await client2.sync();

const tasksResource2 = client2.instantiationService.get(IUserDataProfilesService).defaultProfile.tasksResource;
const fileService2 = client2.instantiationService.get(IFileService);
fileService2.del(tasksResource2);
await client2.sync();

await testObject.sync(await client.getResourceManifest());

assert.deepStrictEqual(testObject.status, SyncStatus.Idle);
const lastSyncUserData = await testObject.getLastSyncUserData();
const remoteUserData = await testObject.getRemoteUserData(null);
assert.strictEqual(getTasksContentFromSyncContent(lastSyncUserData!.syncData!.content!, client.instantiationService.get(ILogService)), null);
assert.strictEqual(getTasksContentFromSyncContent(remoteUserData!.syncData!.content!, client.instantiationService.get(ILogService)), null);
assert.strictEqual(await fileService.exists(tasksResource), false);
});

test('when tasks file is created after first sync', async () => {
const fileService = client.instantiationService.get(IFileService);
const tasksResource = client.instantiationService.get(IUserDataProfilesService).defaultProfile.tasksResource;
Expand Down Expand Up @@ -491,7 +519,7 @@ suite('TasksSync', () => {
assert.deepStrictEqual(server.requests, []);
});

test('sync profile snippets', async () => {
test('sync profile tasks', async () => {
const client2 = disposableStore.add(new UserDataSyncClient(server));
await client2.setUp(true);
const profile = await client2.instantiationService.get(IUserDataProfilesService).createNamedProfile('profile1');
Expand Down

0 comments on commit 942cc4b

Please sign in to comment.