#15756 sync prereleases

This commit is contained in:
Sandeep Somavarapu 2021-11-24 23:37:54 +01:00
parent f26a89c2c3
commit a74b70781e
No known key found for this signature in database
GPG key ID: 1FED25EC4646638B
6 changed files with 226 additions and 73 deletions

View file

@ -6,6 +6,7 @@
import { IStringDictionary } from 'vs/base/common/collections';
import { deepClone, equals } from 'vs/base/common/objects';
import * as semver from 'vs/base/common/semver/semver';
import { isUndefined } from 'vs/base/common/types';
import { IExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { ISyncExtension, ISyncExtensionWithVersion } from 'vs/platform/userDataSync/common/userDataSync';
@ -89,10 +90,12 @@ export function merge(localExtensions: ISyncExtensionWithVersion[], remoteExtens
const localExtension = localExtensionsMap.get(key);
if (localExtension) {
const remoteExtension = remoteExtensionsMap.get(key)!;
const mergedExtension = updatedInRemote ? remoteExtension : localExtension;
return {
...(updatedInRemote ? remoteExtension : localExtension),
...mergedExtension,
version: remoteExtension.version && semver.gt(remoteExtension.version, localExtension.version) ? localExtension.version : localExtension.version,
state: mergeExtensionState(localExtension, remoteExtension, lastSyncExtensionsMap?.get(key))
state: mergeExtensionState(localExtension, remoteExtension, lastSyncExtensionsMap?.get(key)),
preRelease: isUndefined(mergedExtension.preRelease) /* from older client*/ ? localExtension.preRelease : mergedExtension.preRelease
};
}
@ -210,6 +213,7 @@ function compare(from: Map<string, ISyncExtension> | null, to: Map<string, ISync
const toExtension = to.get(key);
if (!toExtension
|| fromExtension.disabled !== toExtension.disabled
|| fromExtension.preRelease !== toExtension.preRelease
|| !isSameExtensionState(fromExtension.state, toExtension.state)
|| (checkVersionProperty && fromExtension.version !== toExtension.version)
|| (checkInstalledProperty && fromExtension.installed !== toExtension.installed)
@ -307,6 +311,7 @@ function massageOutgoingExtension<T extends ISyncExtension>(extension: T, key: s
id: extension.identifier.id,
uuid: key.startsWith('uuid:') ? key.substring('uuid:'.length) : undefined
},
preRelease: !!extension.preRelease /* set it always so that to differentiate with older clients */
};
if (extension.version) {
massagedExtension.version = extension.version;

View file

@ -364,21 +364,24 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
if (e.state && installedExtension.manifest.version === e.version) {
this.updateExtensionState(e.state, installedExtension.manifest.publisher, installedExtension.manifest.name, installedExtension.manifest.version);
}
if (e.disabled) {
this.logService.trace(`${this.syncResourceLogLabel}: Disabling extension...`, e.identifier.id);
await this.extensionEnablementService.disableExtension(e.identifier);
this.logService.info(`${this.syncResourceLogLabel}: Disabled extension`, e.identifier.id);
} else {
this.logService.trace(`${this.syncResourceLogLabel}: Enabling extension...`, e.identifier.id);
await this.extensionEnablementService.enableExtension(e.identifier);
this.logService.info(`${this.syncResourceLogLabel}: Enabled extension`, e.identifier.id);
const isDisabled = this.extensionEnablementService.getDisabledExtensions().some(disabledExtension => areSameExtensions(disabledExtension, e.identifier));
if (isDisabled !== !!e.disabled) {
if (e.disabled) {
this.logService.trace(`${this.syncResourceLogLabel}: Disabling extension...`, e.identifier.id);
await this.extensionEnablementService.disableExtension(e.identifier);
this.logService.info(`${this.syncResourceLogLabel}: Disabled extension`, e.identifier.id);
} else {
this.logService.trace(`${this.syncResourceLogLabel}: Enabling extension...`, e.identifier.id);
await this.extensionEnablementService.enableExtension(e.identifier);
this.logService.info(`${this.syncResourceLogLabel}: Enabled extension`, e.identifier.id);
}
}
removeFromSkipped.push(e.identifier);
return;
}
// User Extension Sync: Install/Update, Enablement & State
const extension = (await this.extensionGalleryService.getExtensions([e.identifier], CancellationToken.None))[0];
const extension = (await this.extensionGalleryService.getExtensions([e.identifier], !!e.preRelease, CancellationToken.None))[0];
/* Update extension state only if
* extension is installed and version is same as synced version or
@ -395,21 +398,25 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
if (extension) {
try {
if (e.disabled) {
this.logService.trace(`${this.syncResourceLogLabel}: Disabling extension...`, e.identifier.id, extension.version);
await this.extensionEnablementService.disableExtension(extension.identifier);
this.logService.info(`${this.syncResourceLogLabel}: Disabled extension`, e.identifier.id, extension.version);
} else {
this.logService.trace(`${this.syncResourceLogLabel}: Enabling extension...`, e.identifier.id, extension.version);
await this.extensionEnablementService.enableExtension(extension.identifier);
this.logService.info(`${this.syncResourceLogLabel}: Enabled extension`, e.identifier.id, extension.version);
const isDisabled = this.extensionEnablementService.getDisabledExtensions().some(disabledExtension => areSameExtensions(disabledExtension, e.identifier));
if (isDisabled !== !!e.disabled) {
if (e.disabled) {
this.logService.trace(`${this.syncResourceLogLabel}: Disabling extension...`, e.identifier.id, extension.version);
await this.extensionEnablementService.disableExtension(extension.identifier);
this.logService.info(`${this.syncResourceLogLabel}: Disabled extension`, e.identifier.id, extension.version);
} else {
this.logService.trace(`${this.syncResourceLogLabel}: Enabling extension...`, e.identifier.id, extension.version);
await this.extensionEnablementService.enableExtension(extension.identifier);
this.logService.info(`${this.syncResourceLogLabel}: Enabled extension`, e.identifier.id, extension.version);
}
}
// Install only if the extension does not exist
if (!installedExtension) {
if (!installedExtension // Install if the extension does not exist
|| installedExtension.hadPreReleaseVersion !== e.preRelease // Install if the extension pre-release preference has changed
) {
if (await this.extensionManagementService.canInstall(extension)) {
this.logService.trace(`${this.syncResourceLogLabel}: Installing extension...`, e.identifier.id, extension.version);
await this.extensionManagementService.installFromGallery(extension, { isMachineScoped: false, donotIncludePackAndDependencies: true } /* pass options to prevent install and sync dialog in web */);
await this.extensionManagementService.installFromGallery(extension, { isMachineScoped: false, donotIncludePackAndDependencies: true, installPreReleaseVersion: e.preRelease } /* pass options to prevent install and sync dialog in web */);
this.logService.info(`${this.syncResourceLogLabel}: Installed extension.`, e.identifier.id, extension.version);
removeFromSkipped.push(extension.identifier);
} else {
@ -465,8 +472,8 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
private getLocalExtensions(installedExtensions: ILocalExtension[]): ISyncExtensionWithVersion[] {
const disabledExtensions = this.extensionEnablementService.getDisabledExtensions();
return installedExtensions
.map(({ identifier, isBuiltin, manifest }) => {
const syncExntesion: ISyncExtensionWithVersion = { identifier, version: manifest.version };
.map(({ identifier, isBuiltin, manifest, hadPreReleaseVersion }) => {
const syncExntesion: ISyncExtensionWithVersion = { identifier, version: manifest.version, preRelease: hadPreReleaseVersion };
if (disabledExtensions.some(disabledExtension => areSameExtensions(disabledExtension, identifier))) {
syncExntesion.disabled = true;
}

View file

@ -301,6 +301,7 @@ export namespace UserDataSyncError {
export interface ISyncExtension {
identifier: IExtensionIdentifier;
preRelease?: boolean;
version?: string;
disabled?: boolean;
installed?: boolean;

View file

@ -117,15 +117,15 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'a', uuid: 'a' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'a', uuid: 'a' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, null, [], []);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' }]);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false }]);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, expected);
@ -141,14 +141,14 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, null, [], ['a']);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' }]);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false }]);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, expected);
@ -170,7 +170,7 @@ suite('ExtensionsMerge', () => {
const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], []);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' }]);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false }]);
assert.deepStrictEqual(actual.local.removed, [{ id: 'a', uuid: 'a' }, { id: 'd', uuid: 'd' }]);
assert.deepStrictEqual(actual.local.updated, []);
assert.strictEqual(actual.remote, null);
@ -193,9 +193,9 @@ suite('ExtensionsMerge', () => {
const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], []);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' }]);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false }]);
assert.deepStrictEqual(actual.local.removed, [{ id: 'a', uuid: 'a' }]);
assert.deepStrictEqual(actual.local.updated, [{ identifier: { id: 'd', uuid: 'd' }, disabled: true, installed: true, version: '1.0.0' }]);
assert.deepStrictEqual(actual.local.updated, [{ identifier: { id: 'd', uuid: 'd' }, disabled: true, installed: true, version: '1.0.0', preRelease: false }]);
assert.strictEqual(actual.remote, null);
});
@ -215,7 +215,7 @@ suite('ExtensionsMerge', () => {
const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], ['a']);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' }]);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false }]);
assert.deepStrictEqual(actual.local.removed, [{ id: 'd', uuid: 'd' }]);
assert.deepStrictEqual(actual.local.updated, []);
assert.strictEqual(actual.remote, null);
@ -239,7 +239,7 @@ suite('ExtensionsMerge', () => {
const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, []);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' }]);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false }, { identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false }]);
assert.deepStrictEqual(actual.local.removed, [{ id: 'd', uuid: 'd' }]);
assert.deepStrictEqual(actual.local.updated, []);
assert.strictEqual(actual.remote, null);
@ -263,7 +263,7 @@ suite('ExtensionsMerge', () => {
const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, ['b']);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' }]);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false }]);
assert.deepStrictEqual(actual.local.removed, [{ id: 'd', uuid: 'd' }]);
assert.deepStrictEqual(actual.local.updated, []);
assert.strictEqual(actual.remote, null);
@ -282,13 +282,17 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'a', uuid: 'a' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], []);
assert.deepStrictEqual(actual.local.added, []);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, localExtensions);
assert.deepStrictEqual(actual.remote?.all, expected);
});
test('merge local and remote extensions when local is moved forwarded with disabled extensions', () => {
@ -305,13 +309,18 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'a', uuid: 'a' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, disabled: true, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], []);
assert.deepStrictEqual(actual.local.added, []);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, localExtensions);
assert.deepStrictEqual(actual.remote?.all, expected);
});
test('merge local and remote extensions when local is moved forwarded with ignored settings', () => {
@ -334,7 +343,7 @@ suite('ExtensionsMerge', () => {
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, [
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false },
]);
});
@ -355,9 +364,9 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, []);
@ -385,8 +394,8 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, ['c']);
@ -413,14 +422,14 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], []);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0' }]);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0', preRelease: false }]);
assert.deepStrictEqual(actual.local.removed, [{ id: 'a', uuid: 'a' }]);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, expected);
@ -442,9 +451,9 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], ['a', 'e']);
@ -473,14 +482,14 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, []);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0' }]);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0', preRelease: false }]);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, expected);
@ -504,9 +513,9 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'e', uuid: 'e' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, ['e']);
@ -528,15 +537,15 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'A', uuid: 'a' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0' },
{ identifier: { id: 'A', uuid: 'a' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'b', uuid: 'b' }, installed: true, version: '1.0.0', preRelease: false },
{ identifier: { id: 'c', uuid: 'c' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, null, [], []);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0' }]);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'd', uuid: 'd' }, installed: true, version: '1.0.0', preRelease: false }]);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, expected);
@ -566,13 +575,16 @@ suite('ExtensionsMerge', () => {
const remoteExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, installed: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, null, [], []);
assert.deepStrictEqual(actual.local.added, []);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, localExtensions);
assert.deepStrictEqual(actual.remote?.all, expected);
});
test('merge when an extension is not an installed extension remotely and does not exist locally', () => {
@ -600,7 +612,7 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'a', uuid: 'a' }, installed: true, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, installed: true, disabled: true, version: '1.0.0' },
{ identifier: { id: 'a', uuid: 'a' }, installed: true, disabled: true, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, remoteExtensions, [], []);
@ -623,7 +635,9 @@ suite('ExtensionsMerge', () => {
assert.deepStrictEqual(actual.local.added, []);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, remoteExtensions);
assert.deepStrictEqual(actual.local.updated, [
{ identifier: { id: 'a', uuid: 'a' }, installed: true, disabled: true, version: '1.0.0', preRelease: false },
]);
assert.deepStrictEqual(actual.remote, null);
});
@ -635,8 +649,8 @@ suite('ExtensionsMerge', () => {
{ identifier: { id: 'b', uuid: 'b' }, version: '1.0.0' },
];
const expected: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'b', uuid: 'b' }, version: '1.0.0' },
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0' },
{ identifier: { id: 'b', uuid: 'b' }, version: '1.0.0', preRelease: false },
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, null, [], []);
@ -647,4 +661,128 @@ suite('ExtensionsMerge', () => {
assert.deepStrictEqual(actual.remote?.all, expected);
});
test('merge: remote extension with prerelease is added', () => {
const localExtensions: ISyncExtensionWithVersion[] = [];
const remoteExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true },
];
const actual = merge(localExtensions, remoteExtensions, null, [], []);
assert.deepStrictEqual(actual.local.added, [{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true }]);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote, null);
});
test('merge: local extension with prerelease is added', () => {
const localExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true },
];
const remoteExtensions: ISyncExtensionWithVersion[] = [];
const actual = merge(localExtensions, remoteExtensions, null, [], []);
assert.deepStrictEqual(actual.local.added, []);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, [{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true }]);
});
test('merge: remote extension with prerelease is added when local extension without prerelease is added', () => {
const localExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true },
];
const remoteExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true },
];
const actual = merge(localExtensions, remoteExtensions, null, [], []);
assert.deepStrictEqual(actual.local.added, []);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, [{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true }]);
assert.deepStrictEqual(actual.remote, null);
});
test('merge: remote extension without prerelease is added when local extension with prerelease is added', () => {
const localExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true },
];
const remoteExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true },
];
const actual = merge(localExtensions, remoteExtensions, null, [], []);
assert.deepStrictEqual(actual.local.added, []);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, [{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true }]);
assert.deepStrictEqual(actual.remote?.all, [{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true }]);
});
test('merge: remote extension is changed to prerelease', () => {
const localExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true },
];
const remoteExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true },
];
const actual = merge(localExtensions, remoteExtensions, localExtensions, [], []);
assert.deepStrictEqual(actual.local.added, []);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, [{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true }]);
assert.deepStrictEqual(actual.remote, null);
});
test('merge: remote extension is changed to release', () => {
const localExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true },
];
const remoteExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: false },
];
const actual = merge(localExtensions, remoteExtensions, localExtensions, [], []);
assert.deepStrictEqual(actual.local.added, []);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, [{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: false }]);
assert.deepStrictEqual(actual.remote, null);
});
test('merge: local extension is changed to prerelease', () => {
const localExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true },
];
const remoteExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true },
];
const actual = merge(localExtensions, remoteExtensions, remoteExtensions, [], []);
assert.deepStrictEqual(actual.local.added, []);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, [{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true }]);
});
test('merge: local extension is changed to release', () => {
const localExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: false },
];
const remoteExtensions: ISyncExtensionWithVersion[] = [
{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: true },
];
const actual = merge(localExtensions, remoteExtensions, remoteExtensions, [], []);
assert.deepStrictEqual(actual.local.added, []);
assert.deepStrictEqual(actual.local.removed, []);
assert.deepStrictEqual(actual.local.updated, []);
assert.deepStrictEqual(actual.remote?.all, [{ identifier: { id: 'a', uuid: 'a' }, version: '1.0.0', installed: true, preRelease: false }]);
});
});

View file

@ -6,6 +6,7 @@
import { CancellationToken } from 'vs/base/common/cancellation';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IExtensionGalleryService, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IFileService } from 'vs/platform/files/common/files';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
@ -124,7 +125,8 @@ class RemoteExtensionsInitializer extends AbstractExtensionsInitializer {
await Promise.allSettled(extensionsToInstall.map(async e => {
const manifest = await this.extensionGalleryService.getManifest(e, CancellationToken.None);
if (manifest && this.extensionManifestPropertiesService.canExecuteOnWorkspace(manifest)) {
await this.extensionManagementService.installFromGallery(e);
const syncedExtension = remoteExtensions.find(e => areSameExtensions(e.identifier, e.identifier));
await this.extensionManagementService.installFromGallery(e, { installPreReleaseVersion: syncedExtension?.preRelease, donotIncludePackAndDependencies: true });
}
}));
}

View file

@ -395,7 +395,7 @@ class NewExtensionsInitializer implements IUserDataInitializer {
storeExtensionStorageState(galleryExtension.publisher, galleryExtension.name, extensionToSync.state, this.storageService);
}
this.logService.trace(`Installing extension...`, galleryExtension.identifier.id);
const local = await this.extensionManagementService.installFromGallery(galleryExtension, { isMachineScoped: false, donotIncludePackAndDependencies: true } /* pass options to prevent install and sync dialog in web */);
const local = await this.extensionManagementService.installFromGallery(galleryExtension, { isMachineScoped: false, donotIncludePackAndDependencies: true, installPreReleaseVersion: extensionToSync.preRelease } /* pass options to prevent install and sync dialog in web */);
if (!preview.disabledExtensions.some(identifier => areSameExtensions(identifier, galleryExtension.identifier))) {
newlyEnabledExtensions.push(local);
}