提交 57d59ad5 编写于 作者: S Sandeep Somavarapu

#66397 Use single identifier for local extension which is gallery one

上级 8c4af495
......@@ -153,7 +153,7 @@ class Main {
return Promise.reject(new Error(`${notFound(version ? `${id}@${version}` : id)}\n${useId}`));
}
const [installedExtension] = installed.filter(e => areSameExtensions(e.galleryIdentifier, { id }));
const [installedExtension] = installed.filter(e => areSameExtensions(e.identifier, { id }));
if (installedExtension) {
if (extension.version !== installedExtension.manifest.version) {
if (version || force) {
......@@ -186,10 +186,10 @@ class Main {
const extensionIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) };
const installedExtensions = await this.extensionManagementService.getInstalled(ExtensionType.User);
const newer = installedExtensions.filter(local => areSameExtensions(extensionIdentifier, local.galleryIdentifier) && semver.gt(local.manifest.version, manifest.version))[0];
const newer = installedExtensions.filter(local => areSameExtensions(extensionIdentifier, local.identifier) && semver.gt(local.manifest.version, manifest.version))[0];
if (newer && !force) {
console.log(localize('forceDowngrade', "A newer version of this extension '{0}' v{1} is already installed. Use '--force' option to downgrade to older version.", newer.galleryIdentifier.id, newer.manifest.version, manifest.version));
console.log(localize('forceDowngrade', "A newer version of this extension '{0}' v{1} is already installed. Use '--force' option to downgrade to older version.", newer.identifier.id, newer.manifest.version, manifest.version));
return false;
}
......@@ -225,7 +225,7 @@ class Main {
return sequence(extensions.map(extension => () => {
return getExtensionId(extension).then(id => {
return this.extensionManagementService.getInstalled(ExtensionType.User).then(installed => {
const [extension] = installed.filter(e => areSameExtensions(e.galleryIdentifier, { id }));
const [extension] = installed.filter(e => areSameExtensions(e.identifier, { id }));
if (!extension) {
return Promise.reject(new Error(`${notInstalled(id)}\n${useId}`));
......
......@@ -7,7 +7,7 @@ import { localize } from 'vs/nls';
import { Event, Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { IExtensionManagementService, DidUninstallExtensionEvent, IExtensionEnablementService, IExtensionIdentifier, EnablementState, isIExtensionIdentifier, DidInstallExtensionEvent, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement';
import { getIdFromLocalExtensionId, areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
......@@ -67,8 +67,8 @@ export class ExtensionEnablementService extends Disposable implements IExtension
const allInstalledExtensions = await this.extensionManagementService.getInstalled();
for (const installedExtension of allInstalledExtensions) {
if (this._isExtensionDisabledInEnvironment(installedExtension)) {
if (!result.some(r => areSameExtensions(r, installedExtension.galleryIdentifier))) {
result.push(installedExtension.galleryIdentifier);
if (!result.some(r => areSameExtensions(r, installedExtension.identifier))) {
result.push(installedExtension.identifier);
}
}
}
......@@ -81,7 +81,7 @@ export class ExtensionEnablementService extends Disposable implements IExtension
if (this._isExtensionDisabledInEnvironment(extension)) {
return EnablementState.Disabled;
}
const identifier = extension.galleryIdentifier;
const identifier = extension.identifier;
if (this.hasWorkspace) {
if (this._getEnabledExtensions(StorageScope.WORKSPACE).filter(e => areSameExtensions(e, identifier))[0]) {
return EnablementState.WorkspaceEnabled;
......@@ -115,7 +115,7 @@ export class ExtensionEnablementService extends Disposable implements IExtension
if (!this.canChangeEnablement(arg)) {
return Promise.resolve(false);
}
identifier = arg.galleryIdentifier;
identifier = arg.identifier;
}
const workspace = newState === EnablementState.WorkspaceDisabled || newState === EnablementState.WorkspaceEnabled;
......@@ -160,7 +160,7 @@ export class ExtensionEnablementService extends Disposable implements IExtension
}
const disabledExtensions = this.environmentService.disableExtensions;
if (Array.isArray(disabledExtensions)) {
return disabledExtensions.some(id => areSameExtensions({ id }, extension.galleryIdentifier));
return disabledExtensions.some(id => areSameExtensions({ id }, extension.identifier));
}
return false;
}
......@@ -297,20 +297,16 @@ export class ExtensionEnablementService extends Disposable implements IExtension
private _onDidInstallExtension(event: DidInstallExtensionEvent): void {
if (event.local && event.operation === InstallOperation.Install) {
const wasDisabled = !this.isEnabled(event.local);
this._reset(event.local.galleryIdentifier);
this._reset(event.local.identifier);
if (wasDisabled) {
this._onEnablementChanged.fire(event.local.galleryIdentifier);
this._onEnablementChanged.fire(event.local.identifier);
}
}
}
private _onDidUninstallExtension({ identifier, error }: DidUninstallExtensionEvent): void {
if (!error) {
const id = getIdFromLocalExtensionId(identifier.id);
if (id) {
const extension = { id, uuid: identifier.uuid };
this._reset(extension);
}
this._reset(identifier);
}
}
......
......@@ -5,7 +5,6 @@
import { ILocalExtension, IGalleryExtension, IExtensionIdentifier, IReportedExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
import { compareIgnoreCase } from 'vs/base/common/strings';
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
export function areSameExtensions(a: IExtensionIdentifier, b: IExtensionIdentifier): boolean {
if (a.uuid && b.uuid) {
......@@ -25,28 +24,6 @@ export function getGalleryExtensionId(publisher: string, name: string): string {
return `${publisher.toLocaleLowerCase()}.${name.toLocaleLowerCase()}`;
}
export const LOCAL_EXTENSION_ID_REGEX = /^([^.]+\..+)-(\d+\.\d+\.\d+(-.*)?)$/;
export function getIdFromLocalExtensionId(localExtensionId: string): string {
const matches = LOCAL_EXTENSION_ID_REGEX.exec(localExtensionId);
if (matches && matches[1]) {
return adoptToGalleryExtensionId(matches[1]);
}
return adoptToGalleryExtensionId(localExtensionId);
}
export function getLocalExtensionIdFromGallery(extension: IGalleryExtension, version: string): string {
return getLocalExtensionId(extension.identifier.id, version);
}
export function getLocalExtensionIdFromManifest(manifest: IExtensionManifest): string {
return getLocalExtensionId(getGalleryExtensionId(manifest.publisher, manifest.name), manifest.version);
}
export function getLocalExtensionId(id: string, version: string): string {
return `${id}-${version}`;
}
export function groupByExtension<T>(extensions: T[], getExtensionIdentifier: (t: T) => IExtensionIdentifier): T[][] {
const byExtension: T[][] = [];
const findGroup = extension => {
......@@ -70,7 +47,7 @@ export function groupByExtension<T>(extensions: T[], getExtensionIdentifier: (t:
export function getLocalExtensionTelemetryData(extension: ILocalExtension): any {
return {
id: extension.galleryIdentifier.id,
id: extension.identifier.id,
name: extension.manifest.name,
galleryId: null,
publisherId: extension.metadata ? extension.metadata.publisherId : null,
......
......@@ -29,10 +29,10 @@ export class ExtensionsLifecycle extends Disposable {
async postUninstall(extension: ILocalExtension): Promise<void> {
const script = this.parseScript(extension, 'uninstall');
if (script) {
this.logService.info(extension.identifier.id, `Running post uninstall script`);
this.logService.info(extension.identifier.id, extension.manifest.version, `Running post uninstall script`);
await this.processesLimiter.queue(() =>
this.runLifecycleHook(script.script, 'uninstall', script.args, true, extension)
.then(() => this.logService.info(extension.identifier.id, `Finished running post uninstall script`), err => this.logService.error(extension.identifier.id, `Failed to run post uninstall script: ${err}`)));
.then(() => this.logService.info(extension.identifier.id, extension.manifest.version, `Finished running post uninstall script`), err => this.logService.error(extension.identifier.id, extension.manifest.version, `Failed to run post uninstall script: ${err}`)));
}
return rimraf(this.getExtensionStoragePath(extension)).then(undefined, e => this.logService.error('Error while removing extension storage path', e));
}
......@@ -42,7 +42,7 @@ export class ExtensionsLifecycle extends Disposable {
if (extension.location.scheme === Schemas.file && extension.manifest && extension.manifest['scripts'] && typeof extension.manifest['scripts'][scriptKey] === 'string') {
const script = (<string>extension.manifest['scripts'][scriptKey]).split(' ');
if (script.length < 2 || script[0] !== 'node' || !script[1]) {
this.logService.warn(extension.identifier.id, `${scriptKey} should be a node script`);
this.logService.warn(extension.identifier.id, extension.manifest.version, `${scriptKey} should be a node script`);
return null;
}
return { script: posix.join(extension.location.fsPath, script[1]), args: script.slice(2) || [] };
......@@ -105,8 +105,8 @@ export class ExtensionsLifecycle extends Disposable {
const onStderr = Event.fromNodeEventEmitter<string>(extensionUninstallProcess.stderr, 'data');
// Log output
onStdout(data => this.logService.info(extension.identifier.id, `post-${lifecycleType}`, data));
onStderr(data => this.logService.error(extension.identifier.id, `post-${lifecycleType}`, data));
onStdout(data => this.logService.info(extension.identifier.id, extension.manifest.version, `post-${lifecycleType}`, data));
onStderr(data => this.logService.error(extension.identifier.id, extension.manifest.version, `post-${lifecycleType}`, data));
const onOutput = Event.any(
Event.map(onStdout, o => ({ data: `%c${o}`, format: [''] })),
......@@ -130,6 +130,6 @@ export class ExtensionsLifecycle extends Disposable {
}
private getExtensionStoragePath(extension: ILocalExtension): string {
return posix.join(this.environmentService.globalStorageHome, extension.galleryIdentifier.id.toLowerCase());
return posix.join(this.environmentService.globalStorageHome, extension.identifier.id.toLowerCase());
}
}
......@@ -3,26 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as semver from 'semver';
import { adoptToGalleryExtensionId, LOCAL_EXTENSION_ID_REGEX } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { buffer } from 'vs/platform/node/zip';
import { localize } from 'vs/nls';
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
export function getIdAndVersionFromLocalExtensionId(localExtensionId: string): { id: string, version: string | null } {
const matches = LOCAL_EXTENSION_ID_REGEX.exec(localExtensionId);
if (matches && matches[1] && matches[2]) {
const version = semver.valid(matches[2]);
if (version) {
return { id: adoptToGalleryExtensionId(matches[1]), version };
}
}
return {
id: adoptToGalleryExtensionId(localExtensionId),
version: null
};
}
export function getManifest(vsix: string): Promise<IExtensionManifest> {
return buffer(vsix, 'extension/package.json')
.then(buffer => {
......
......@@ -87,7 +87,7 @@ suite('ExtensionEnablementService Test', () => {
const target = sinon.spy();
testObject.onEnablementChanged(target);
return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)
.then(() => assert.ok(target.calledWithExactly({ id: 'pub.a', uuid: undefined })));
.then(() => assert.ok(target.calledWithExactly({ id: 'pub.a' })));
});
test('test disable an extension globally again should return a falsy promise', () => {
......@@ -199,7 +199,7 @@ suite('ExtensionEnablementService Test', () => {
return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled)
.then(() => testObject.onEnablementChanged(target))
.then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled))
.then(() => assert.ok(target.calledWithExactly({ id: 'pub.a', uuid: undefined })));
.then(() => assert.ok(target.calledWithExactly({ id: 'pub.a' })));
});
test('test disable an extension globally and then for workspace', () => {
......@@ -220,7 +220,7 @@ suite('ExtensionEnablementService Test', () => {
return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)
.then(() => testObject.onEnablementChanged(target))
.then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled))
.then(() => assert.ok(target.calledWithExactly({ id: 'pub.a', uuid: undefined })));
.then(() => assert.ok(target.calledWithExactly({ id: 'pub.a' })));
});
test('test disable an extension for workspace when there is no workspace throws error', () => {
......@@ -247,7 +247,7 @@ suite('ExtensionEnablementService Test', () => {
return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)
.then(() => testObject.onEnablementChanged(target))
.then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Enabled))
.then(() => assert.ok(target.calledWithExactly({ id: 'pub.a', uuid: undefined })));
.then(() => assert.ok(target.calledWithExactly({ id: 'pub.a' })));
});
test('test enable an extension globally when already enabled return falsy promise', () => {
......@@ -273,7 +273,7 @@ suite('ExtensionEnablementService Test', () => {
return testObject.setEnablement(aLocalExtension('pub.b'), EnablementState.WorkspaceDisabled)
.then(() => testObject.onEnablementChanged(target))
.then(() => testObject.setEnablement(aLocalExtension('pub.b'), EnablementState.WorkspaceEnabled))
.then(() => assert.ok(target.calledWithExactly({ id: 'pub.b', uuid: undefined })));
.then(() => assert.ok(target.calledWithExactly({ id: 'pub.b' })));
});
test('test enable an extension for workspace when already enabled return truthy promise', () => {
......@@ -300,7 +300,7 @@ suite('ExtensionEnablementService Test', () => {
test('test installing an extension re-eanbles it when disabled globally', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement(local, EnablementState.Disabled);
didInstallEvent.fire({ local, identifier: local.galleryIdentifier, operation: InstallOperation.Install });
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
const extensions = await testObject.getDisabledExtensions();
assert.deepEqual([], extensions);
});
......@@ -308,7 +308,7 @@ suite('ExtensionEnablementService Test', () => {
test('test updating an extension does not re-eanbles it when disabled globally', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement(local, EnablementState.Disabled);
didInstallEvent.fire({ local, identifier: local.galleryIdentifier, operation: InstallOperation.Update });
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
const extensions = await testObject.getDisabledExtensions();
assert.deepEqual([{ id: 'pub.a' }], extensions);
});
......@@ -318,11 +318,11 @@ suite('ExtensionEnablementService Test', () => {
await testObject.setEnablement(local, EnablementState.Disabled);
return new Promise((c, e) => {
testObject.onEnablementChanged(e => {
if (e.id === local.galleryIdentifier.id) {
if (e.id === local.identifier.id) {
c();
}
});
didInstallEvent.fire({ local, identifier: local.galleryIdentifier, operation: InstallOperation.Install });
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
});
});
......@@ -331,14 +331,14 @@ suite('ExtensionEnablementService Test', () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement(local, EnablementState.Disabled);
testObject.onEnablementChanged(target);
didInstallEvent.fire({ local, identifier: local.galleryIdentifier, operation: InstallOperation.Update });
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
assert.ok(!target.called);
});
test('test installing an extension re-eanbles it when workspace disabled', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement(local, EnablementState.WorkspaceDisabled);
didInstallEvent.fire({ local, identifier: local.galleryIdentifier, operation: InstallOperation.Install });
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
const extensions = await testObject.getDisabledExtensions();
assert.deepEqual([], extensions);
});
......@@ -346,7 +346,7 @@ suite('ExtensionEnablementService Test', () => {
test('test updating an extension does not re-eanbles it when workspace disabled', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement(local, EnablementState.WorkspaceDisabled);
didInstallEvent.fire({ local, identifier: local.galleryIdentifier, operation: InstallOperation.Update });
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
const extensions = await testObject.getDisabledExtensions();
assert.deepEqual([{ id: 'pub.a' }], extensions);
});
......@@ -356,11 +356,11 @@ suite('ExtensionEnablementService Test', () => {
await testObject.setEnablement(local, EnablementState.WorkspaceDisabled);
return new Promise((c, e) => {
testObject.onEnablementChanged(e => {
if (e.id === local.galleryIdentifier.id) {
if (e.id === local.identifier.id) {
c();
}
});
didInstallEvent.fire({ local, identifier: local.galleryIdentifier, operation: InstallOperation.Install });
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
});
});
......@@ -369,7 +369,7 @@ suite('ExtensionEnablementService Test', () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement(local, EnablementState.WorkspaceDisabled);
testObject.onEnablementChanged(target);
didInstallEvent.fire({ local, identifier: local.galleryIdentifier, operation: InstallOperation.Update });
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
assert.ok(!target.called);
});
......@@ -377,14 +377,14 @@ suite('ExtensionEnablementService Test', () => {
const target = sinon.spy();
const local = aLocalExtension('pub.a');
testObject.onEnablementChanged(target);
didInstallEvent.fire({ local, identifier: local.galleryIdentifier, operation: InstallOperation.Install });
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
assert.ok(!target.called);
});
test('test remove an extension from disablement list when uninstalled', () => {
return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled)
.then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled))
.then(() => didUninstallEvent.fire({ identifier: { id: 'pub.a-1.0.0' } }))
.then(() => didUninstallEvent.fire({ identifier: { id: 'pub.a' } }))
.then(() => testObject.getDisabledExtensions())
.then(extensions => assert.deepEqual([], extensions));
});
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { getGalleryExtensionId, areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import * as strings from 'vs/base/common/strings';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { ILocalization } from 'vs/platform/localizations/common/localizations';
......@@ -111,6 +111,24 @@ export interface IExtensionContributions {
export type ExtensionKind = 'ui' | 'workspace';
export class ExtensionIdentifierWithVersion {
constructor(
readonly identifier: IExtensionIdentifier,
readonly version: string
) { }
key(): string {
return `${this.identifier.id}-${this.version}`;
}
equals(o: any): boolean {
if (!(o instanceof ExtensionIdentifierWithVersion)) {
return false;
}
return areSameExtensions(this.identifier, o.identifier) && this.version === o.version;
}
}
export interface IExtensionIdentifier {
id: string;
uuid?: string;
......@@ -145,7 +163,6 @@ export const enum ExtensionType {
export interface IExtension {
readonly type: ExtensionType;
readonly identifier: IExtensionIdentifier;
readonly galleryIdentifier: IExtensionIdentifier; /** This should be removed */
readonly manifest: IExtensionManifest;
readonly location: URI;
}
......
......@@ -9,7 +9,7 @@ import { IExtensionManagementService, ILocalExtension, IExtensionIdentifier } fr
import { Disposable } from 'vs/base/common/lifecycle';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { Queue } from 'vs/base/common/async';
import { areSameExtensions, getIdFromLocalExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ILogService } from 'vs/platform/log/common/log';
import { isValidLocalization, ILocalizationsService, LanguageType } from 'vs/platform/localizations/common/localizations';
import product from 'vs/platform/node/product';
......@@ -68,7 +68,7 @@ export class LocalizationsService extends Disposable implements ILocalizationsSe
private onDidInstallExtension(extension: ILocalExtension | undefined): void {
if (extension && extension.manifest && extension.manifest.contributes && extension.manifest.contributes.localizations && extension.manifest.contributes.localizations.length) {
this.logService.debug('Adding language packs from the extension', extension.galleryIdentifier.id);
this.logService.debug('Adding language packs from the extension', extension.identifier.id);
this.update();
}
}
......@@ -76,7 +76,6 @@ export class LocalizationsService extends Disposable implements ILocalizationsSe
private onDidUninstallExtension(identifier: IExtensionIdentifier): void {
this.cache.getLanguagePacks()
.then(languagePacks => {
identifier = { id: getIdFromLocalExtensionId(identifier.id), uuid: identifier.uuid };
if (Object.keys(languagePacks).some(language => languagePacks[language] && languagePacks[language].extensions.some(e => areSameExtensions(e.extensionIdentifier, identifier)))) {
this.logService.debug('Removing language packs from the extension', identifier.id);
this.update();
......@@ -136,7 +135,7 @@ class LanguagePacksCache extends Disposable {
}
private createLanguagePacksFromExtension(languagePacks: { [language: string]: ILanguagePack }, extension: ILocalExtension): void {
const extensionIdentifier = extension.galleryIdentifier;
const extensionIdentifier = extension.identifier;
const localizations = extension.manifest.contributes && extension.manifest.contributes.localizations ? extension.manifest.contributes.localizations : [];
for (const localizationContribution of localizations) {
if (extension.location.scheme === Schemas.file && isValidLocalization(localizationContribution)) {
......
......@@ -26,7 +26,7 @@ import { assign } from 'vs/base/common/objects';
import { URI } from 'vs/base/common/uri';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { lastSessionDateStorageKey } from 'vs/platform/telemetry/node/workbenchCommonProperties';
import { getLocalExtensionIdFromManifest, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
interface ExperimentSettings {
......@@ -46,8 +46,7 @@ function aLocalExtension(name: string = 'someext', manifest: any = {}, propertie
properties = assign({
type: ExtensionType.User,
location: URI.file(`pub.${name}`),
identifier: { id: getLocalExtensionIdFromManifest(manifest) },
galleryIdentifier: { id: getGalleryExtensionId(manifest.publisher, manifest.name), uuid: undefined },
identifier: { id: getGalleryExtensionId(manifest.publisher, manifest.name), uuid: undefined },
metadata: { id: getGalleryExtensionId(manifest.publisher, manifest.name), publisherId: manifest.publisher, publisherDisplayName: 'somename' }
}, properties);
return <ILocalExtension>Object.create({ manifest, ...properties });
......
......@@ -421,7 +421,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
}
this.extensionsService.getInstalled(ExtensionType.User).then(local => {
const recommendations = filteredRecs.filter(({ extensionId }) => local.every(local => !areSameExtensions({ id: extensionId }, local.galleryIdentifier)));
const recommendations = filteredRecs.filter(({ extensionId }) => local.every(local => !areSameExtensions({ id: extensionId }, local.identifier)));
if (!recommendations.length) {
return Promise.resolve(undefined);
......
......@@ -748,7 +748,7 @@ export class InstallInRemoteServerAction extends ExtensionAction {
this.storageService.store('askToInstallRemoteServerExtension', false, StorageScope.GLOBAL);
}
}
const galleryExtension = this.extension.gallery ? this.extension.gallery : await this.extensionGalleryService.getExtension(this.extension.local!.galleryIdentifier);
const galleryExtension = this.extension.gallery ? this.extension.gallery : await this.extensionGalleryService.getExtension(this.extension.local!.identifier);
if (galleryExtension) {
return this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.installFromGallery(galleryExtension);
} else {
......
......@@ -14,7 +14,6 @@ import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { getIdAndVersionFromLocalExtensionId } from 'vs/platform/extensionManagement/node/extensionManagementUtil';
import { Severity, INotificationService } from 'vs/platform/notification/common/notification';
import product from 'vs/platform/node/product';
......@@ -48,9 +47,9 @@ export class KeymapExtensions implements IWorkbenchContribution {
private checkForOtherKeymaps(extensionIdentifier: IExtensionIdentifier): Promise<void> {
return this.instantiationService.invokeFunction(getInstalledExtensions).then(extensions => {
const keymaps = extensions.filter(extension => isKeymapExtension(this.tipsService, extension));
const extension = arrays.first(keymaps, extension => stripVersion(extension.identifier.id) === extensionIdentifier.id);
const extension = arrays.first(keymaps, extension => areSameExtensions(extension.identifier, extensionIdentifier));
if (extension && extension.globallyEnabled) {
const otherKeymaps = keymaps.filter(extension => stripVersion(extension.identifier.id) !== extensionIdentifier.id && extension.globallyEnabled);
const otherKeymaps = keymaps.filter(extension => !areSameExtensions(extension.identifier, extensionIdentifier) && extension.globallyEnabled);
if (otherKeymaps.length) {
return this.promptForDisablingOtherKeymaps(extension, otherKeymaps);
}
......@@ -105,7 +104,7 @@ export function onExtensionChanged(accessor: ServicesAccessor): Event<IExtension
.event;
return Event.debounce<IExtensionIdentifier, IExtensionIdentifier[]>(Event.any(
Event.chain(Event.any(onDidInstallExtension, extensionService.onDidUninstallExtension))
.map(e => ({ id: stripVersion(e.identifier.id), uuid: e.identifier.uuid }))
.map(e => e.identifier)
.event,
extensionEnablementService.onEnablementChanged
), (list, id) => {
......@@ -126,9 +125,9 @@ export function getInstalledExtensions(accessor: ServicesAccessor): Promise<IExt
.then(disabledExtensions => {
return extensions.map(extension => {
return {
identifier: extension.galleryIdentifier,
identifier: extension.identifier,
local: extension,
globallyEnabled: disabledExtensions.every(disabled => !areSameExtensions(disabled, extension.galleryIdentifier))
globallyEnabled: disabledExtensions.every(disabled => !areSameExtensions(disabled, extension.identifier))
};
});
});
......@@ -137,11 +136,7 @@ export function getInstalledExtensions(accessor: ServicesAccessor): Promise<IExt
export function isKeymapExtension(tipsService: IExtensionTipsService, extension: IExtensionStatus): boolean {
const cats = extension.local.manifest.categories;
return cats && cats.indexOf('Keymaps') !== -1 || tipsService.getKeymapRecommendations().some(({ extensionId }) => areSameExtensions({ id: extensionId }, extension.local.galleryIdentifier));
}
function stripVersion(id: string): string {
return getIdAndVersionFromLocalExtensionId(id).id;
return cats && cats.indexOf('Keymaps') !== -1 || tipsService.getKeymapRecommendations().some(({ extensionId }) => areSameExtensions({ id: extensionId }, extension.local.identifier));
}
export function getKeywordsForExtension(extension: string): string[] {
......
......@@ -635,13 +635,13 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution {
return this.extensionsManagementService.getInstalled(ExtensionType.User).then(installed => {
const maliciousExtensions = installed
.filter(e => maliciousSet.has(e.galleryIdentifier.id));
.filter(e => maliciousSet.has(e.identifier.id));
if (maliciousExtensions.length) {
return Promise.all(maliciousExtensions.map(e => this.extensionsManagementService.uninstall(e, true).then(() => {
this.notificationService.prompt(
Severity.Warning,
localize('malicious warning', "We have uninstalled '{0}' which was reported to be problematic.", e.galleryIdentifier.id),
localize('malicious warning', "We have uninstalled '{0}' which was reported to be problematic.", e.identifier.id),
[{
label: localize('reloadNow', "Reload Now"),
run: () => this.windowService.reloadWindow()
......
......@@ -232,7 +232,7 @@ export class ExtensionsListView extends ViewletPanel {
&& e.local.manifest.contributes
&& Array.isArray(e.local.manifest.contributes.grammars)
&& e.local.manifest.contributes.grammars.length
&& e.local.galleryIdentifier.id !== 'vscode.git';
&& e.local.identifier.id !== 'vscode.git';
});
return this.getPagedModel(this.sortExtensions(basics, options));
}
......@@ -240,7 +240,7 @@ export class ExtensionsListView extends ViewletPanel {
const others = result.filter(e => {
return e.local.manifest
&& e.local.manifest.contributes
&& (!Array.isArray(e.local.manifest.contributes.grammars) || e.local.galleryIdentifier.id === 'vscode.git')
&& (!Array.isArray(e.local.manifest.contributes.grammars) || e.local.identifier.id === 'vscode.git')
&& !Array.isArray(e.local.manifest.contributes.themes);
});
return this.getPagedModel(this.sortExtensions(others, options));
......
......@@ -16,7 +16,7 @@ import {
IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions,
InstallExtensionEvent, DidInstallExtensionEvent, DidUninstallExtensionEvent, IExtensionEnablementService, IExtensionIdentifier, EnablementState, IExtensionManagementServerService
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, areSameExtensions, getMaliciousExtensionsSet, getLocalExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, areSameExtensions, getMaliciousExtensionsSet } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWindowService } from 'vs/platform/windows/common/windows';
......@@ -37,7 +37,7 @@ import * as resources from 'vs/base/common/resources';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IFileService } from 'vs/platform/files/common/files';
import { IExtensionManifest, ExtensionType } from 'vs/platform/extensions/common/extensions';
import { IExtensionManifest, ExtensionType, ExtensionIdentifierWithVersion } from 'vs/platform/extensions/common/extensions';
interface IExtensionStateProvider<T> {
(extension: Extension): T;
......@@ -78,11 +78,11 @@ class Extension implements IExtension {
if (this.gallery) {
return this.gallery.identifier;
}
return this.local.galleryIdentifier;
return this.local.identifier;
}
get uuid(): string | undefined {
return this.gallery ? this.gallery.identifier.uuid : this.local.galleryIdentifier.uuid;
return this.gallery ? this.gallery.identifier.uuid : this.local.identifier.uuid;
}
get publisher(): string {
......@@ -433,12 +433,12 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
.then(installed => this.getDistinctInstalledExtensions(installed)
.then(distinctInstalled => {
const installedById = index(this.installed, e => e.identifier.id);
const groupById = groupBy(installed, i => i.galleryIdentifier.id);
const groupById = groupBy(installed, i => i.identifier.id);
this.installed = distinctInstalled.map(local => {
const locals = groupById[local.galleryIdentifier.id];
const locals = groupById[local.identifier.id];
locals.splice(locals.indexOf(local), 1);
locals.splice(0, 0, local);
const extension = installedById[local.galleryIdentifier.id] || new Extension(this.galleryService, this.stateProvider, locals, undefined, this.telemetryService, this.logService, this.fileService);
const extension = installedById[local.identifier.id] || new Extension(this.galleryService, this.stateProvider, locals, undefined, this.telemetryService, this.logService, this.fileService);
extension.locals = locals;
extension.enablementState = this.extensionEnablementService.getEnablementState(local);
return extension;
......@@ -498,7 +498,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
return Promise.all([this.runtimeExtensionService.getExtensions(), this.extensionEnablementService.getDisabledExtensions()])
.then(([runtimeExtensions, disabledExtensionIdentifiers]) => {
const groups = groupBy(allInstalled, (extension: ILocalExtension) => {
const isDisabled = disabledExtensionIdentifiers.some(identifier => areSameExtensions(identifier, extension.galleryIdentifier));
const isDisabled = disabledExtensionIdentifiers.some(identifier => areSameExtensions(identifier, extension.identifier));
if (isDisabled) {
return extension.location.scheme === Schemas.file ? 'disabled:primary' : 'disabled:secondary';
} else {
......@@ -511,20 +511,20 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
for (const extension of (groups['enabled'] || [])) {
if (runtimeExtensions.some(r => r.extensionLocation.toString() === extension.location.toString())) {
enabled.push(extension);
seenExtensions[extension.galleryIdentifier.id] = true;
seenExtensions[extension.identifier.id] = true;
} else {
notRunningExtensions.push(extension);
}
}
for (const extension of notRunningExtensions) {
if (!seenExtensions[extension.galleryIdentifier.id]) {
if (!seenExtensions[extension.identifier.id]) {
enabled.push(extension);
seenExtensions[extension.galleryIdentifier.id] = true;
seenExtensions[extension.identifier.id] = true;
}
}
const primaryDisabled = groups['disabled:primary'] || [];
const secondaryDisabled = (groups['disabled:secondary'] || []).filter(disabled => {
return primaryDisabled.every(p => !areSameExtensions(p.galleryIdentifier, disabled.galleryIdentifier));
return primaryDisabled.every(p => !areSameExtensions(p.identifier, disabled.identifier));
});
return [...enabled, ...primaryDisabled, ...secondaryDisabled];
});
......@@ -533,10 +533,10 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
private hasDuplicates(extensions: ILocalExtension[]): boolean {
const seen: { [key: string]: boolean; } = Object.create(null);
for (const i of extensions) {
if (seen[i.galleryIdentifier.id]) {
if (seen[i.identifier.id]) {
return true;
}
seen[i.galleryIdentifier.id] = true;
seen[i.identifier.id] = true;
}
return false;
}
......@@ -646,7 +646,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
const toUpdate = this.local.filter(e =>
e.outdated && e.state !== ExtensionState.Installing
&& e.local && !this.isAutoUpdateIgnored(e.local.galleryIdentifier.id, e.local.manifest.version));
&& e.local && !this.isAutoUpdateIgnored(new ExtensionIdentifierWithVersion(e.identifier, e.version)));
return Promise.all(toUpdate.map(e => this.install(e)));
}
......@@ -709,7 +709,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
return this.progressService.withProgress({
location: ProgressLocation.Extensions,
title: nls.localize('uninstallingExtension', 'Uninstalling extension....'),
source: `${toUninstall[0].galleryIdentifier.id}`
source: `${toUninstall[0].identifier.id}`
}, () => Promise.all(toUninstall.map(local => this.extensionService.uninstall(local))).then(() => undefined));
}
......@@ -731,7 +731,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
() => this.extensionService.installFromGallery(gallery)
.then(() => {
if (extension.latestVersion !== version) {
this.ignoreAutoUpdate(gallery.identifier.id, version);
this.ignoreAutoUpdate(new ExtensionIdentifierWithVersion(gallery.identifier, version));
}
})
, gallery.displayName);
......@@ -752,7 +752,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
return this.progressService.withProgress({
location: ProgressLocation.Extensions,
source: `${toReinstall[0].galleryIdentifier.id}`
source: `${toReinstall[0].identifier.id}`
}, () => Promise.all(toReinstall.map(local => this.extensionService.reinstallFromGallery(local))).then(() => undefined));
}
......@@ -952,34 +952,30 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
this._onChange.fire(error ? undefined : extension);
}
private onUninstallExtension({ id }: IExtensionIdentifier): void {
this.logService.info(`Uninstalling the extension ${id} from window ${this.windowService.getCurrentWindowId()}`);
const extension = this.installed.filter(e => e.local.identifier.id === id)[0];
const newLength = this.installed.filter(e => e.local.identifier.id !== id).length;
// TODO: Ask @Joao why is this?
if (newLength === this.installed.length) {
private onUninstallExtension(identifier: IExtensionIdentifier): void {
const extension = this.installed.filter(e => areSameExtensions(e.identifier, identifier))[0];
if (!extension) {
return;
}
const uninstalling = this.uninstalling.filter(e => e.local.identifier.id === id)[0] || extension;
this.uninstalling = [uninstalling, ...this.uninstalling.filter(e => e.local.identifier.id !== id)];
const uninstalling = this.uninstalling.filter(e => areSameExtensions(e.identifier, identifier))[0] || extension;
this.uninstalling = [uninstalling, ...this.uninstalling.filter(e => !areSameExtensions(e.identifier, identifier))];
this._onChange.fire(undefined);
this._onChange.fire(uninstalling);
}
private onDidUninstallExtension({ identifier, error }: DidUninstallExtensionEvent): void {
const id = identifier.id;
if (!error) {
this.installed = this.installed.filter(e => e.local.identifier.id !== id);
this.installed = this.installed.filter(e => !areSameExtensions(e.identifier, identifier));
}
const uninstalling = this.uninstalling.filter(e => e.local.identifier.id === id)[0];
this.uninstalling = this.uninstalling.filter(e => e.local.identifier.id !== id);
const uninstalling = this.uninstalling.filter(e => areSameExtensions(e.identifier, identifier))[0];
this.uninstalling = this.uninstalling.filter(e => !areSameExtensions(e.identifier, identifier));
if (!uninstalling) {
return;
}
this._onChange.fire(undefined);
this._onChange.fire(uninstalling);
}
private onEnablementChanged(identifier: IExtensionIdentifier) {
......@@ -1084,19 +1080,18 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
this.storageService.store('extensions.ignoredAutoUpdateExtension', JSON.stringify(this._ignoredAutoUpdateExtensions), StorageScope.GLOBAL);
}
private ignoreAutoUpdate(galleryId: string, version: string): void {
if (!this.isAutoUpdateIgnored(galleryId, version)) {
this.ignoredAutoUpdateExtensions = [...this.ignoredAutoUpdateExtensions, getLocalExtensionId(galleryId, version)];
private ignoreAutoUpdate(identifierWithVersion: ExtensionIdentifierWithVersion): void {
if (!this.isAutoUpdateIgnored(identifierWithVersion)) {
this.ignoredAutoUpdateExtensions = [...this.ignoredAutoUpdateExtensions, identifierWithVersion.key()];
}
}
private isAutoUpdateIgnored(galleryId: string, version: string): boolean {
const extensionId = getLocalExtensionId(galleryId, version).toLowerCase();
return this.ignoredAutoUpdateExtensions.indexOf(extensionId) !== -1;
private isAutoUpdateIgnored(identifierWithVersion: ExtensionIdentifierWithVersion): boolean {
return this.ignoredAutoUpdateExtensions.indexOf(identifierWithVersion.key()) !== -1;
}
private resetIgnoreAutoUpdateExtensions(): void {
this.ignoredAutoUpdateExtensions = this.ignoredAutoUpdateExtensions.filter(extensionId => this.local.some(local => !!local.local && local.local.identifier.id.toLowerCase() === extensionId));
this.ignoredAutoUpdateExtensions = this.ignoredAutoUpdateExtensions.filter(extensionId => this.local.some(local => !!local.local && new ExtensionIdentifierWithVersion(local.identifier, local.version).key() === extensionId));
}
dispose(): void {
......
......@@ -13,7 +13,7 @@ import {
IExtensionManagementService, IExtensionGalleryService, IExtensionEnablementService, IExtensionTipsService, ILocalExtension, IGalleryExtension,
DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, EnablementState, InstallOperation, IExtensionManagementServerService, IExtensionManagementServer
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { getGalleryExtensionId, getLocalExtensionIdFromManifest, getLocalExtensionIdFromGallery } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
import { ExtensionTipsService } from 'vs/workbench/parts/extensions/electron-browser/extensionTipsService';
import { TestExtensionEnablementService } from 'vs/platform/extensionManagement/test/electron-browser/extensionEnablementService.test';
......@@ -1109,11 +1109,11 @@ suite('ExtensionsActions Test', () => {
return instantiationService.get(IExtensionsWorkbenchService).queryGallery()
.then((paged) => {
testObject.extension = paged.firstPage[0];
const identifier = { id: getLocalExtensionIdFromGallery(gallery, gallery.version) };
installEvent.fire({ identifier: identifier, gallery });
didInstallEvent.fire({ identifier: identifier, gallery, operation: InstallOperation.Install, local: aLocalExtension('a', gallery, { identifier }) });
const identifier = gallery.identifier;
installEvent.fire({ identifier, gallery });
didInstallEvent.fire({ identifier, gallery, operation: InstallOperation.Install, local: aLocalExtension('a', gallery, { identifier }) });
uninstallEvent.fire(identifier);
didUninstallEvent.fire({ identifier: identifier });
didUninstallEvent.fire({ identifier });
assert.ok(!testObject.enabled);
});
......@@ -1152,9 +1152,9 @@ suite('ExtensionsActions Test', () => {
didUninstallEvent.fire({ identifier: local.identifier });
const gallery = aGalleryExtension('a');
const id = getLocalExtensionIdFromGallery(gallery, gallery.version);
installEvent.fire({ identifier: { id }, gallery });
didInstallEvent.fire({ identifier: { id }, gallery, operation: InstallOperation.Install, local });
const identifier = gallery.identifier;
installEvent.fire({ identifier, gallery });
didInstallEvent.fire({ identifier, gallery, operation: InstallOperation.Install, local });
assert.ok(!testObject.enabled);
});
......@@ -1345,8 +1345,7 @@ suite('ExtensionsActions Test', () => {
properties = assign({
type: ExtensionType.User,
location: URI.file(`pub.${name}`),
identifier: { id: getLocalExtensionIdFromManifest(manifest) },
galleryIdentifier: { id: getGalleryExtensionId(manifest.publisher, manifest.name), uuid: undefined },
identifier: { id: getGalleryExtensionId(manifest.publisher, manifest.name), uuid: undefined },
metadata: { id: getGalleryExtensionId(manifest.publisher, manifest.name), publisherId: manifest.publisher, publisherDisplayName: 'somename' }
}, properties);
return <ILocalExtension>Object.create({ manifest, ...properties });
......
......@@ -14,7 +14,7 @@ import {
IExtensionManagementService, IExtensionGalleryService, IExtensionEnablementService, IExtensionTipsService, ILocalExtension, IGalleryExtension, IQueryOptions,
DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, IExtensionManagementServerService, IExtensionManagementServer, EnablementState, ExtensionRecommendationReason, SortBy
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { getGalleryExtensionId, getLocalExtensionIdFromManifest } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
import { ExtensionTipsService } from 'vs/workbench/parts/extensions/electron-browser/extensionTipsService';
import { TestExtensionEnablementService } from 'vs/platform/extensionManagement/test/electron-browser/extensionEnablementService.test';
......@@ -124,11 +124,11 @@ suite('ExtensionsListView Tests', () => {
instantiationService.stub(IExtensionService, {
getExtensions: () => {
return Promise.resolve([
{ identifier: new ExtensionIdentifier(localEnabledTheme.galleryIdentifier.id) },
{ identifier: new ExtensionIdentifier(localEnabledLanguage.galleryIdentifier.id) },
{ identifier: new ExtensionIdentifier(localRandom.galleryIdentifier.id) },
{ identifier: new ExtensionIdentifier(builtInTheme.galleryIdentifier.id) },
{ identifier: new ExtensionIdentifier(builtInBasic.galleryIdentifier.id) }
{ identifier: new ExtensionIdentifier(localEnabledTheme.identifier.id) },
{ identifier: new ExtensionIdentifier(localEnabledLanguage.identifier.id) },
{ identifier: new ExtensionIdentifier(localRandom.identifier.id) },
{ identifier: new ExtensionIdentifier(builtInTheme.identifier.id) },
{ identifier: new ExtensionIdentifier(builtInBasic.identifier.id) }
]);
}
});
......@@ -503,8 +503,7 @@ suite('ExtensionsListView Tests', () => {
properties = assign({
type: ExtensionType.User,
location: URI.file(`pub.${name}`),
identifier: { id: getLocalExtensionIdFromManifest(manifest) },
galleryIdentifier: { id: getGalleryExtensionId(manifest.publisher, manifest.name), uuid: undefined },
identifier: { id: getGalleryExtensionId(manifest.publisher, manifest.name), uuid: undefined },
metadata: { id: getGalleryExtensionId(manifest.publisher, manifest.name), publisherId: manifest.publisher, publisherDisplayName: 'somename' }
}, properties);
return <ILocalExtension>Object.create({ manifest, ...properties });
......
......@@ -14,7 +14,7 @@ import {
IExtensionManagementService, IExtensionGalleryService, IExtensionEnablementService, IExtensionTipsService, ILocalExtension, IGalleryExtension,
DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IGalleryExtensionAssets, IExtensionIdentifier, EnablementState, InstallOperation
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { getGalleryExtensionId, getLocalExtensionIdFromManifest, getLocalExtensionIdFromGallery } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
import { ExtensionTipsService } from 'vs/workbench/parts/extensions/electron-browser/extensionTipsService';
import { TestExtensionEnablementService } from 'vs/platform/extensionManagement/test/electron-browser/extensionEnablementService.test';
......@@ -329,7 +329,7 @@ suite('ExtensionsWorkbenchServiceTest', () => {
assert.equal(ExtensionState.Uninstalled, extension.state);
testObject.install(extension);
const identifier = { id: getLocalExtensionIdFromGallery(gallery, gallery.version) };
const identifier = gallery.identifier;
// Installing
installEvent.fire({ identifier, gallery });
......@@ -1186,8 +1186,7 @@ suite('ExtensionsWorkbenchServiceTest', () => {
properties = assign({
type: ExtensionType.User,
location: URI.file(`pub.${name}`),
identifier: { id: getLocalExtensionIdFromManifest(manifest) },
galleryIdentifier: { id: getGalleryExtensionId(manifest.publisher, manifest.name), uuid: undefined },
identifier: { id: getGalleryExtensionId(manifest.publisher, manifest.name), uuid: undefined },
metadata: { id: getGalleryExtensionId(manifest.publisher, manifest.name), publisherId: manifest.publisher, publisherDisplayName: 'somename' }
}, properties);
return <ILocalExtension>Object.create({ manifest, ...properties });
......
......@@ -49,7 +49,7 @@ export class PreferencesSearchService extends Disposable implements IPreferences
return exts
.filter(ext => this.extensionEnablementService.isEnabled(ext))
.filter(ext => ext.manifest && ext.manifest.contributes && ext.manifest.contributes.configuration)
.filter(ext => !!ext.galleryIdentifier.uuid);
.filter(ext => !!ext.identifier.uuid);
});
}
......@@ -197,7 +197,7 @@ class RemoteSearchProvider implements ISearchProvider {
.filter(k => {
const result = remoteResult.scoredResults[k];
const resultExtId = (result.extensionPublisher + '.' + result.extensionName).toLowerCase();
return !installedExtensions.some(ext => ext.galleryIdentifier.id.toLowerCase() === resultExtId);
return !installedExtensions.some(ext => ext.identifier.id.toLowerCase() === resultExtId);
})
.filter(k => remoteResult.scoredResults[k].score >= newExtsMinScore);
......@@ -393,7 +393,7 @@ class RemoteSearchProvider implements ISearchProvider {
}
private getExtensionFilter(ext: ILocalExtension): string {
const uuid = ext.galleryIdentifier.uuid;
const uuid = ext.identifier.uuid;
const versionString = ext.manifest.version
.split('.')
.map(versionPart => strings.pad(<any>versionPart, 10))
......
......@@ -35,7 +35,6 @@ import { getExtraColor } from 'vs/workbench/parts/welcome/walkThrough/node/walkT
import { IExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/common/extensions';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IEditorInputFactory, EditorInput } from 'vs/workbench/common/editor';
import { getIdAndVersionFromLocalExtensionId } from 'vs/platform/extensionManagement/node/extensionManagementUtil';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { TimeoutTimer } from 'vs/base/common/async';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
......@@ -385,7 +384,7 @@ class WelcomePage {
this.updateInstalledExtensions(container, installedExtensions);
this.disposables.push(this.instantiationService.invokeFunction(onExtensionChanged)(ids => {
for (const id of ids) {
if (container.querySelector(`.installExtension[data-extension="${stripVersion(id.id)}"], .enabledExtension[data-extension="${stripVersion(id.id)}"]`)) {
if (container.querySelector(`.installExtension[data-extension="${id.id}"], .enabledExtension[data-extension="${id.id}"]`)) {
const installedExtensions = this.instantiationService.invokeFunction(getInstalledExtensions);
this.updateInstalledExtensions(container, installedExtensions);
break;
......@@ -442,7 +441,7 @@ class WelcomePage {
extensionId: extensionSuggestion.id,
});
this.instantiationService.invokeFunction(getInstalledExtensions).then(extensions => {
const installedExtension = arrays.first(extensions, extension => stripVersion(extension.identifier.id) === extensionSuggestion.id);
const installedExtension = arrays.first(extensions, extension => areSameExtensions(extension.identifier, { id: extensionSuggestion.id }));
if (installedExtension && installedExtension.globallyEnabled) {
/* __GDPR__FRAGMENT__
"WelcomePageInstalled-1" : {
......@@ -468,7 +467,7 @@ class WelcomePage {
return this.extensionManagementService.installFromGallery(extension)
.then(() => this.extensionManagementService.getInstalled(ExtensionType.User))
.then(installed => {
const local = installed.filter(i => areSameExtensions(extension.identifier, i.galleryIdentifier))[0];
const local = installed.filter(i => areSameExtensions(extension.identifier, i.identifier))[0];
// TODO: Do this as part of the install to avoid multiple events.
return this.extensionEnablementService.setEnablement(local, EnablementState.Disabled).then(() => local);
});
......@@ -587,7 +586,7 @@ class WelcomePage {
elements[i].classList.remove('installed');
}
extensions.filter(ext => ext.globallyEnabled)
.map(ext => stripVersion(ext.identifier.id))
.map(ext => ext.identifier.id)
.forEach(id => {
const install = container.querySelectorAll(`.installExtension[data-extension="${id}"]`);
for (let i = 0; i < install.length; i++) {
......@@ -606,11 +605,6 @@ class WelcomePage {
}
}
function stripVersion(id: string): string {
return getIdAndVersionFromLocalExtensionId(id).id;
}
export class WelcomeInputFactory implements IEditorInputFactory {
static readonly ID = welcomeInputTypeId;
......
......@@ -493,7 +493,7 @@ export class ExtensionService extends Disposable implements IExtensionService {
if (extensionsToDisable.length) {
return this._extensionManagementService.getInstalled(ExtensionType.User)
.then(installed => {
const toDisable = installed.filter(i => extensionsToDisable.some(e => areSameExtensions(i.galleryIdentifier, e)));
const toDisable = installed.filter(i => extensionsToDisable.some(e => areSameExtensions(i.identifier, e)));
return Promise.all(toDisable.map(e => this._extensionEnablementService.setEnablement(e, EnablementState.Disabled)));
})
.then(() => {
......
......@@ -148,7 +148,7 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
private async handleUnhandledURL(uri: URI, extensionIdentifier: IExtensionIdentifier): Promise<void> {
const installedExtensions = await this.extensionManagementService.getInstalled();
const extension = installedExtensions.filter(e => areSameExtensions(e.galleryIdentifier, extensionIdentifier))[0];
const extension = installedExtensions.filter(e => areSameExtensions(e.identifier, extensionIdentifier))[0];
// Extension is installed
if (extension) {
......
......@@ -12,11 +12,10 @@ import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages';
import * as types from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import * as pfs from 'vs/base/node/pfs';
import { getGalleryExtensionId, getLocalExtensionId, groupByExtension } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { getIdAndVersionFromLocalExtensionId } from 'vs/platform/extensionManagement/node/extensionManagementUtil';
import { getGalleryExtensionId, groupByExtension } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { isValidExtensionVersion } from 'vs/platform/extensions/node/extensionValidator';
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { ExtensionIdentifier, ExtensionIdentifierWithVersion } from 'vs/platform/extensions/common/extensions';
const MANIFEST_FILE = 'package.json';
......@@ -557,27 +556,13 @@ export class ExtensionScanner {
refs.sort((a, b) => a.name < b.name ? -1 : 1);
if (!isBuiltin) {
// TODO: align with extensionsService
const nonGallery: IExtensionReference[] = [];
const gallery: IExtensionReference[] = [];
refs.forEach(ref => {
if (ref.name.indexOf('.') !== 0) { // Do not consider user extension folder starting with `.`
const { id, version } = getIdAndVersionFromLocalExtensionId(ref.name);
if (!id || !version) {
nonGallery.push(ref);
} else {
gallery.push(ref);
}
}
});
refs = [...nonGallery, ...gallery];
refs = refs.filter(ref => ref.name.indexOf('.') !== 0); // Do not consider user extension folder starting with `.`
}
const nlsConfig = ExtensionScannerInput.createNLSConfig(input);
let _extensionDescriptions = await Promise.all(refs.map(r => this.scanExtension(input.ourVersion, log, r.path, isBuiltin, isUnderDevelopment, nlsConfig)));
let extensionDescriptions = arrays.coalesce(_extensionDescriptions);
extensionDescriptions = extensionDescriptions.filter(item => item !== null && !obsolete[getLocalExtensionId(getGalleryExtensionId(item.publisher, item.name), item.version)]);
extensionDescriptions = extensionDescriptions.filter(item => item !== null && !obsolete[new ExtensionIdentifierWithVersion({ id: getGalleryExtensionId(item.publisher, item.name) }, item.version).key()]);
if (!isBuiltin) {
// Filter out outdated extensions
......
......@@ -40,7 +40,7 @@ export class WorkbenchIssueService implements IWorkbenchIssueService {
repositoryUrl: manifest.repository && manifest.repository.url,
bugsUrl: manifest.bugs && manifest.bugs.url,
displayName: manifest.displayName,
id: extension.galleryIdentifier.id,
id: extension.identifier.id,
isTheme: isTheme
};
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册