Skip to content

Commit

Permalink
#48430 Read dependencies with new format (optional property)
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 committed Jul 12, 2018
1 parent 25200ef commit b8bd640
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export interface IExtensionManifest {
icon?: string;
categories?: string[];
activationEvents?: string[];
extensionDependencies?: string[];
extensionDependencies?: IExtensionDependency[];
contributes?: IExtensionContributions;
repository?: {
url: string;
Expand All @@ -133,8 +133,13 @@ export interface IExtensionManifest {
};
}

export interface IExtensionDependency {
id: string;
optional: boolean;
}

export interface IGalleryExtensionProperties {
dependencies?: string[];
dependencies?: IExtensionDependency[];
engine?: string;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import * as path from 'path';
import { TPromise } from 'vs/base/common/winjs.base';
import { distinct } from 'vs/base/common/arrays';
import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors';
import { StatisticType, IGalleryExtension, IExtensionGalleryService, IGalleryExtensionAsset, IQueryOptions, SortBy, SortOrder, IExtensionManifest, IExtensionIdentifier, IReportedExtension, InstallOperation, ITranslation } from 'vs/platform/extensionManagement/common/extensionManagement';
import { StatisticType, IGalleryExtension, IExtensionGalleryService, IGalleryExtensionAsset, IQueryOptions, SortBy, SortOrder, IExtensionManifest, IExtensionIdentifier, IReportedExtension, InstallOperation, ITranslation, IExtensionDependency } from 'vs/platform/extensionManagement/common/extensionManagement';
import { getGalleryExtensionId, getGalleryExtensionTelemetryData, adoptToGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { assign, getOrDefault } from 'vs/base/common/objects';
import { IRequestService } from 'vs/platform/request/node/request';
Expand Down Expand Up @@ -262,10 +262,18 @@ function getVersionAsset(version: IRawGalleryExtensionVersion, type: string): IG
};
}

function getDependencies(version: IRawGalleryExtensionVersion): string[] {
function getDependencies(version: IRawGalleryExtensionVersion): IExtensionDependency[] {
const values = version.properties ? version.properties.filter(p => p.key === PropertyType.Dependency) : [];
const value = values.length > 0 && values[0].value;
return value ? value.split(',').map(v => adoptToGalleryExtensionId(v)) : [];
return value ? value.split(',').map(v => {
let dependency: IExtensionDependency;
try {
dependency = JSON.parse(v);
} catch (e) {
dependency = <IExtensionDependency>{ id: v, optional: false };
}
return <IExtensionDependency>{ id: adoptToGalleryExtensionId(dependency.id), optional: dependency.optional };
}) : [];
}

function getEngine(version: IRawGalleryExtensionVersion): string {
Expand Down Expand Up @@ -621,7 +629,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
const dependenciesSet = new Set<string>();
for (const dep of loadedDependencies) {
if (dep.properties.dependencies) {
dep.properties.dependencies.forEach(d => dependenciesSet.add(d));
dep.properties.dependencies.forEach(d => dependenciesSet.add(d.id));
}
}
result = distinct(result.concat(loadedDependencies), d => d.identifier.uuid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import {
StatisticType,
IExtensionIdentifier,
IReportedExtension,
InstallOperation
InstallOperation,
IExtensionDependency
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { getGalleryExtensionIdFromLocal, adoptToGalleryExtensionId, areSameExtensions, getGalleryExtensionId, groupByExtension, getMaliciousExtensionsSet, getLocalExtensionId, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, getIdFromLocalExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { localizeManifest } from '../common/extensionNls';
Expand Down Expand Up @@ -382,13 +383,13 @@ export class ExtensionManagementService extends Disposable implements IExtension
return errors.length ? TPromise.wrapError(this.joinErrors(errors)) : TPromise.as(null);
}

private getDependenciesToInstall(dependencies: string[]): TPromise<IGalleryExtension[]> {
private getDependenciesToInstall(dependencies: IExtensionDependency[]): TPromise<IGalleryExtension[]> {
if (dependencies.length) {
return this.getInstalled()
.then(installed => {
const uninstalledDeps = dependencies.filter(d => installed.every(i => getGalleryExtensionId(i.manifest.publisher, i.manifest.name) !== d));
const uninstalledDeps = dependencies.filter(d => installed.every(i => !areSameExtensions(i.galleryIdentifier, { id: d.id })));
if (uninstalledDeps.length) {
return this.galleryService.loadAllDependencies(uninstalledDeps.map(id => (<IExtensionIdentifier>{ id })))
return this.galleryService.loadAllDependencies(uninstalledDeps.map(dep => (<IExtensionIdentifier>{ id: dep.id })))
.then(allDependencies => allDependencies.filter(d => {
const extensionId = getLocalExtensionIdFromGallery(d, d.version);
return installed.every(({ identifier }) => identifier.id !== extensionId);
Expand Down Expand Up @@ -568,7 +569,7 @@ export class ExtensionManagementService extends Disposable implements IExtension

private hasDependencies(extension: ILocalExtension, installed: ILocalExtension[]): boolean {
if (extension.manifest.extensionDependencies && extension.manifest.extensionDependencies.length) {
return installed.some(i => extension.manifest.extensionDependencies.indexOf(getGalleryExtensionIdFromLocal(i)) !== -1);
return installed.some(i => extension.manifest.extensionDependencies.some(dep => areSameExtensions({ id: dep.id }, i.galleryIdentifier)));
}
return false;
}
Expand Down Expand Up @@ -630,7 +631,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
if (!extension.manifest.extensionDependencies || extension.manifest.extensionDependencies.length === 0) {
return [];
}
const dependenciesToUninstall = installed.filter(i => extension.manifest.extensionDependencies.indexOf(getGalleryExtensionIdFromLocal(i)) !== -1);
const dependenciesToUninstall = installed.filter(i => extension.manifest.extensionDependencies.some(dep => areSameExtensions({ id: dep.id }, i.galleryIdentifier)));
const depsOfDeps = [];
for (const dep of dependenciesToUninstall) {
depsOfDeps.push(...this.getDependenciesToUninstallRecursively(dep, installed, checked));
Expand All @@ -652,7 +653,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
}

private getDependents(extension: ILocalExtension, installed: ILocalExtension[]): ILocalExtension[] {
return installed.filter(e => e.manifest.extensionDependencies && e.manifest.extensionDependencies.indexOf(getGalleryExtensionIdFromLocal(extension)) !== -1);
return installed.filter(e => e.manifest.extensionDependencies && e.manifest.extensionDependencies.some(dep => areSameExtensions({ id: dep.id }, extension.galleryIdentifier)));
}

private doUninstall(extension: ILocalExtension): TPromise<void> {
Expand Down Expand Up @@ -758,9 +759,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
const readmeUrl = readme ? URI.file(path.join(extensionPath, readme)).toString() : null;
const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
const changelogUrl = changelog ? URI.file(path.join(extensionPath, changelog)).toString() : null;
if (manifest.extensionDependencies) {
manifest.extensionDependencies = manifest.extensionDependencies.map(id => adoptToGalleryExtensionId(id));
}
manifest.extensionDependencies = manifest.extensionDependencies ? manifest.extensionDependencies.map(dep => typeof dep === 'string' ? { id: adoptToGalleryExtensionId(dep), optional: false } : { id: adoptToGalleryExtensionId(dep.id), optional: dep.optional }) : [];
const identifier = { id: type === LocalExtensionType.System ? folderName : getLocalExtensionIdFromManifest(manifest), uuid: metadata ? metadata.id : null };
const galleryIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name), uuid: identifier.uuid };
return { type, identifier, galleryIdentifier, manifest, metadata, location: URI.file(extensionPath), readmeUrl, changelogUrl };
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/parts/extensions/common/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
import { Event } from 'vs/base/common/event';
import { TPromise } from 'vs/base/common/winjs.base';
import { IPager } from 'vs/base/common/paging';
import { IQueryOptions, IExtensionManifest, LocalExtensionType, EnablementState, ILocalExtension, IGalleryExtension, ExtensionRecommendationSource } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IQueryOptions, IExtensionManifest, LocalExtensionType, EnablementState, ILocalExtension, IGalleryExtension, ExtensionRecommendationSource, IExtensionDependency } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IViewContainersRegistry, ViewContainer, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views';
import { Registry } from 'vs/platform/registry/common/platform';

Expand Down Expand Up @@ -48,7 +48,7 @@ export interface IExtension {
ratingCount: number;
outdated: boolean;
enablementState: EnablementState;
dependencies: string[];
dependencies: IExtensionDependency[];
telemetryData: any;
preview: boolean;
getManifest(): TPromise<IExtensionManifest>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { IPager, mapPager, singlePagePager } from 'vs/base/common/paging';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import {
IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions, IExtensionManifest,
InstallExtensionEvent, DidInstallExtensionEvent, LocalExtensionType, DidUninstallExtensionEvent, IExtensionEnablementService, IExtensionIdentifier, EnablementState, IExtensionTipsService, ExtensionRecommendationSource, IExtensionRecommendation, IExtensionManagementServerService
InstallExtensionEvent, DidInstallExtensionEvent, LocalExtensionType, DidUninstallExtensionEvent, IExtensionEnablementService, IExtensionIdentifier, EnablementState, IExtensionTipsService, ExtensionRecommendationSource, IExtensionRecommendation, IExtensionManagementServerService, IExtensionDependency
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { getGalleryExtensionIdFromLocal, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, areSameExtensions, getMaliciousExtensionsSet } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
Expand Down Expand Up @@ -262,7 +262,7 @@ ${this.description}
return TPromise.wrapError<string>(new Error('not available'));
}

get dependencies(): string[] {
get dependencies(): IExtensionDependency[] {
const { local, gallery } = this;
if (gallery && !this.isGalleryOutdated()) {
return gallery.properties.dependencies;
Expand Down Expand Up @@ -303,7 +303,7 @@ class ExtensionDependencies implements IExtensionDependencies {
if (!this.hasDependencies) {
return [];
}
return this._extension.dependencies.map(d => new ExtensionDependencies(this._map.get(d), d, this._map, this));
return this._extension.dependencies.map(d => new ExtensionDependencies(this._map.get(d.id), d.id, this._map, this));
}

private computeHasDependencies(): boolean {
Expand Down Expand Up @@ -439,7 +439,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
.then(([allRecommendations, report]) => {
const maliciousSet = getMaliciousExtensionsSet(report);

return this.galleryService.loadAllDependencies((<Extension>extension).dependencies.map(id => <IExtensionIdentifier>{ id }))
return this.galleryService.loadAllDependencies((<Extension>extension).dependencies.map(dep => <IExtensionIdentifier>{ id: dep.id }))
.then(galleryExtensions => galleryExtensions.map(galleryExtension => this.fromGallery(galleryExtension, maliciousSet, allRecommendations)))
.then(extensions => [...this.local, ...extensions])
.then(extensions => {
Expand Down Expand Up @@ -774,7 +774,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
if (i.enablementState === enablementState) {
return false;
}
return i.type === LocalExtensionType.User && extensions.some(extension => extension.dependencies.indexOf(i.id) !== -1);
return i.type === LocalExtensionType.User && extensions.some(extension => extension.dependencies.some(dep => areSameExtensions({ id: dep.id }, i)));
});
if (dependenciesToDisable.length) {
const depsOfDeps = this.getDependenciesRecursively(dependenciesToDisable, installed, enablementState, checked);
Expand All @@ -799,17 +799,17 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
return false;
}
return i.dependencies.some(dep => {
if (extension.id === dep) {
if (extension.id === dep.id) {
return true;
}
return extensionsToDisable.some(d => d.id === dep);
return extensionsToDisable.some(d => d.id === dep.id);
});
});
}

private getDependentsErrorMessage(extension: IExtension, allDisabledExtensions: IExtension[], dependents: IExtension[]): string {
for (const e of [extension, ...allDisabledExtensions]) {
let dependentsOfTheExtension = dependents.filter(d => d.dependencies.some(id => areSameExtensions({ id }, e)));
let dependentsOfTheExtension = dependents.filter(d => d.dependencies.some(dep => areSameExtensions({ id: dep.id }, e)));
if (dependentsOfTheExtension.length) {
return this.getErrorMessageForDisablingAnExtensionWithDependents(e, dependentsOfTheExtension);
}
Expand Down

0 comments on commit b8bd640

Please sign in to comment.