提交 a4dd9113 编写于 作者: S Sandeep Somavarapu

Use uris for changelog and readme of extension and transform them.

上级 0214ede6
......@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { URI, UriComponents } from 'vs/base/common/uri';
import { MarshalledObject } from 'vs/base/common/marshalling';
export interface IURITransformer {
transformIncoming(uri: UriComponents): UriComponents;
......@@ -21,4 +22,83 @@ export const DefaultURITransformer: IURITransformer = new class {
transformOutgoing(uri: URI | UriComponents): URI | UriComponents {
return uri;
}
};
\ No newline at end of file
};
function _transformOutgoingURIs(obj: any, transformer: IURITransformer, depth: number): any {
if (!obj || depth > 200) {
return null;
}
if (typeof obj === 'object') {
if (obj instanceof URI) {
return transformer.transformOutgoing(obj);
}
// walk object (or array)
for (let key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
const r = _transformOutgoingURIs(obj[key], transformer, depth + 1);
if (r !== null) {
obj[key] = r;
}
}
}
}
return null;
}
export function transformOutgoingURIs<T>(obj: T, transformer: IURITransformer): T {
const result = _transformOutgoingURIs(obj, transformer, 0);
if (result === null) {
// no change
return obj;
}
return result;
}
function _transformIncomingURIs(obj: any, transformer: IURITransformer, revive: boolean, depth: number): any {
if (!obj || depth > 200) {
return null;
}
if (typeof obj === 'object') {
if ((<MarshalledObject>obj).$mid === 1) {
return revive ? URI.revive(transformer.transformIncoming(obj)) : transformer.transformIncoming(obj);
}
// walk object (or array)
for (let key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
const r = _transformIncomingURIs(obj[key], transformer, revive, depth + 1);
if (r !== null) {
obj[key] = r;
}
}
}
}
return null;
}
export function transformIncomingURIs<T>(obj: T, transformer: IURITransformer): T {
const result = _transformIncomingURIs(obj, transformer, false, 0);
if (result === null) {
// no change
return obj;
}
return result;
}
export function transformAndReviveIncomingURIs<T>(obj: T, transformer: IURITransformer): T {
const result = _transformIncomingURIs(obj, transformer, true, 0);
if (result === null) {
// no change
return obj;
}
return result;
}
\ No newline at end of file
......@@ -43,7 +43,6 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { DownloadService } from 'vs/platform/download/node/downloadService';
import { IDownloadService } from 'vs/platform/download/common/download';
import { StaticRouter } from 'vs/base/parts/ipc/node/ipc';
import { DefaultURITransformer } from 'vs/base/common/uriIpc';
export interface ISharedProcessConfiguration {
readonly machineId: string;
......@@ -133,7 +132,7 @@ function main(server: Server, initData: ISharedProcessInitData, configuration: I
instantiationService2.invokeFunction(accessor => {
const extensionManagementService = accessor.get(IExtensionManagementService);
const channel = new ExtensionManagementChannel(extensionManagementService, () => DefaultURITransformer);
const channel = new ExtensionManagementChannel(extensionManagementService, () => null);
server.registerChannel('extensions', channel);
// clean up deprecated extensions
......
......@@ -223,8 +223,8 @@ export interface ILocalExtension {
manifest: IExtensionManifest;
metadata: IGalleryMetadata;
location: URI;
readmeUrl: string;
changelogUrl: string;
readmeUrl: URI | null;
changelogUrl: URI | null;
}
export const IExtensionManagementService = createDecorator<IExtensionManagementService>('extensionManagementService');
......
......@@ -6,8 +6,30 @@
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/node/ipc';
import { IExtensionManagementService, ILocalExtension, InstallExtensionEvent, DidInstallExtensionEvent, IGalleryExtension, LocalExtensionType, DidUninstallExtensionEvent, IExtensionIdentifier, IGalleryMetadata, IReportedExtension } from '../common/extensionManagement';
import { Event } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { IURITransformer } from 'vs/base/common/uriIpc';
import { URI, UriComponents } from 'vs/base/common/uri';
import { IURITransformer, DefaultURITransformer, transformAndReviveIncomingURIs } from 'vs/base/common/uriIpc';
import { cloneAndChange } from 'vs/base/common/objects';
function transformIncomingURI(uri: UriComponents, transformer: IURITransformer | null): URI {
return URI.revive(transformer ? transformer.transformIncoming(uri) : uri);
}
function transformOutgoingURI(uri: URI, transformer: IURITransformer | null): URI {
return transformer ? transformer.transformOutgoing(uri) : uri;
}
function transformIncomingExtension(extension: ILocalExtension, transformer: IURITransformer | null): ILocalExtension {
transformer = transformer ? transformer : DefaultURITransformer;
const manfiest = extension.manifest;
extension.manifest = undefined;
extension = transformAndReviveIncomingURIs(extension, transformer);
extension.manifest = manfiest;
return extension;
}
function transformOutgoingExtension(extension: ILocalExtension, transformer: IURITransformer | null): ILocalExtension {
return transformer ? cloneAndChange(extension, value => value instanceof URI ? transformer.transformOutgoing(value) : undefined) : extension;
}
export class ExtensionManagementChannel implements IServerChannel {
......@@ -16,7 +38,7 @@ export class ExtensionManagementChannel implements IServerChannel {
onUninstallExtension: Event<IExtensionIdentifier>;
onDidUninstallExtension: Event<DidUninstallExtensionEvent>;
constructor(private service: IExtensionManagementService, private getUriTransformer: (requestContext: any) => IURITransformer) {
constructor(private service: IExtensionManagementService, private getUriTransformer: (requestContext: any) => IURITransformer | null) {
this.onInstallExtension = Event.buffer(service.onInstallExtension, true);
this.onDidInstallExtension = Event.buffer(service.onDidInstallExtension, true);
this.onUninstallExtension = Event.buffer(service.onUninstallExtension, true);
......@@ -27,7 +49,7 @@ export class ExtensionManagementChannel implements IServerChannel {
const uriTransformer = this.getUriTransformer(context);
switch (event) {
case 'onInstallExtension': return this.onInstallExtension;
case 'onDidInstallExtension': return Event.map(this.onDidInstallExtension, i => ({ ...i, local: this._transformOutgoing(i.local, uriTransformer) }));
case 'onDidInstallExtension': return Event.map(this.onDidInstallExtension, i => ({ ...i, local: transformOutgoingExtension(i.local, uriTransformer) }));
case 'onUninstallExtension': return this.onUninstallExtension;
case 'onDidUninstallExtension': return this.onDidUninstallExtension;
}
......@@ -36,31 +58,21 @@ export class ExtensionManagementChannel implements IServerChannel {
}
call(context, command: string, args?: any): Promise<any> {
const uriTransformer = this.getUriTransformer(context);
const uriTransformer: IURITransformer | null = this.getUriTransformer(context);
switch (command) {
case 'zip': return this.service.zip(this._transformIncoming(args[0], uriTransformer)).then(uri => uriTransformer.transformOutgoing(uri));
case 'unzip': return this.service.unzip(URI.revive(uriTransformer.transformIncoming(args[0])), args[1]);
case 'install': return this.service.install(URI.revive(uriTransformer.transformIncoming(args[0])));
case 'zip': return this.service.zip(transformIncomingExtension(args[0], uriTransformer)).then(uri => transformOutgoingURI(uri, uriTransformer));
case 'unzip': return this.service.unzip(transformIncomingURI(args[0], uriTransformer), args[1]);
case 'install': return this.service.install(transformIncomingURI(args[0], uriTransformer));
case 'installFromGallery': return this.service.installFromGallery(args[0]);
case 'uninstall': return this.service.uninstall(this._transformIncoming(args[0], uriTransformer), args[1]);
case 'reinstallFromGallery': return this.service.reinstallFromGallery(this._transformIncoming(args[0], uriTransformer));
case 'getInstalled': return this.service.getInstalled(args[0]).then(extensions => extensions.map(e => this._transformOutgoing(e, uriTransformer)));
case 'updateMetadata': return this.service.updateMetadata(this._transformIncoming(args[0], uriTransformer), args[1]).then(e => this._transformOutgoing(e, uriTransformer));
case 'uninstall': return this.service.uninstall(transformIncomingExtension(args[0], uriTransformer), args[1]);
case 'reinstallFromGallery': return this.service.reinstallFromGallery(transformIncomingExtension(args[0], uriTransformer));
case 'getInstalled': return this.service.getInstalled(args[0]).then(extensions => extensions.map(e => transformOutgoingExtension(e, uriTransformer)));
case 'updateMetadata': return this.service.updateMetadata(transformIncomingExtension(args[0], uriTransformer), args[1]).then(e => transformOutgoingExtension(e, uriTransformer));
case 'getExtensionsReport': return this.service.getExtensionsReport();
}
throw new Error('Invalid call');
}
private _transformIncoming(extension: ILocalExtension, uriTransformer: IURITransformer): ILocalExtension {
return extension ? { ...extension, ...{ location: URI.revive(uriTransformer.transformIncoming(extension.location)) } } : extension;
}
private _transformOutgoing(extension: ILocalExtension, uriTransformer: IURITransformer): ILocalExtension;
private _transformOutgoing(extension: ILocalExtension | undefined, uriTransformer: IURITransformer): ILocalExtension | undefined;
private _transformOutgoing(extension: ILocalExtension | undefined, uriTransformer: IURITransformer): ILocalExtension | undefined {
return extension ? { ...extension, ...{ location: uriTransformer.transformOutgoing(extension.location) } } : extension;
}
}
export class ExtensionManagementChannelClient implements IExtensionManagementService {
......@@ -70,7 +82,7 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer
constructor(private channel: IChannel) { }
get onInstallExtension(): Event<InstallExtensionEvent> { return this.channel.listen('onInstallExtension'); }
get onDidInstallExtension(): Event<DidInstallExtensionEvent> { return Event.map(this.channel.listen<DidInstallExtensionEvent>('onDidInstallExtension'), i => ({ ...i, local: this._transformIncoming(i.local) })); }
get onDidInstallExtension(): Event<DidInstallExtensionEvent> { return Event.map(this.channel.listen<DidInstallExtensionEvent>('onDidInstallExtension'), i => ({ ...i, local: transformIncomingExtension(i.local, null) })); }
get onUninstallExtension(): Event<IExtensionIdentifier> { return this.channel.listen('onUninstallExtension'); }
get onDidUninstallExtension(): Event<DidUninstallExtensionEvent> { return this.channel.listen('onDidUninstallExtension'); }
......@@ -100,21 +112,15 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer
getInstalled(type: LocalExtensionType | null = null): Promise<ILocalExtension[]> {
return Promise.resolve(this.channel.call<ILocalExtension[]>('getInstalled', [type]))
.then(extensions => extensions.map(extension => this._transformIncoming(extension)));
.then(extensions => extensions.map(extension => transformIncomingExtension(extension, null)));
}
updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise<ILocalExtension> {
return Promise.resolve(this.channel.call<ILocalExtension>('updateMetadata', [local, metadata]))
.then(extension => this._transformIncoming(extension));
.then(extension => transformIncomingExtension(extension, null));
}
getExtensionsReport(): Promise<IReportedExtension[]> {
return Promise.resolve(this.channel.call('getExtensionsReport'));
}
private _transformIncoming(extension: ILocalExtension): ILocalExtension;
private _transformIncoming(extension: ILocalExtension | undefined): ILocalExtension | undefined;
private _transformIncoming(extension: ILocalExtension | undefined): ILocalExtension | undefined {
return extension ? { ...extension, ...{ location: URI.revive(extension.location) } } : extension;
}
}
\ No newline at end of file
......@@ -776,9 +776,9 @@ export class ExtensionManagementService extends Disposable implements IExtension
.then(children => readManifest(extensionPath)
.then(({ manifest, metadata }) => {
const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0];
const readmeUrl = readme ? URI.file(path.join(extensionPath, readme)).toString() : null;
const readmeUrl = readme ? URI.file(path.join(extensionPath, readme)) : null;
const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
const changelogUrl = changelog ? URI.file(path.join(extensionPath, changelog)).toString() : null;
const changelogUrl = changelog ? URI.file(path.join(extensionPath, changelog)) : null;
if (manifest.extensionDependencies) {
manifest.extensionDependencies = manifest.extensionDependencies.map(id => adoptToGalleryExtensionId(id));
}
......
......@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { readFile } from 'vs/base/node/pfs';
import * as semver from 'semver';
import { Event, Emitter } from 'vs/base/common/event';
import { index, distinct } from 'vs/base/common/arrays';
......@@ -37,6 +36,7 @@ import { Schemas } from 'vs/base/common/network';
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';
interface IExtensionStateProvider<T> {
(extension: Extension): T;
......@@ -53,7 +53,8 @@ class Extension implements IExtension {
public locals: ILocalExtension[],
public gallery: IGalleryExtension | undefined,
private telemetryService: ITelemetryService,
private logService: ILogService
private logService: ILogService,
private fileService: IFileService
) { }
get type(): LocalExtensionType | undefined {
......@@ -237,8 +238,7 @@ class Extension implements IExtension {
}
if (this.local && this.local.readmeUrl) {
const uri = URI.parse(this.local.readmeUrl);
return readFile(uri.fsPath, 'utf8');
return this.fileService.resolveContent(this.local.readmeUrl, { encoding: 'utf8' }).then(content => content.value);
}
if (this.type === LocalExtensionType.System) {
......@@ -258,8 +258,7 @@ ${this.description}
}
if (this.local && this.local.changelogUrl) {
const uri = URI.parse(this.local.changelogUrl);
return uri.scheme === 'file';
return true;
}
return this.type === LocalExtensionType.System;
......@@ -280,13 +279,7 @@ ${this.description}
return Promise.reject(new Error('not available'));
}
const uri = URI.parse(changelogUrl);
if (uri.scheme === 'file') {
return readFile(uri.fsPath, 'utf8');
}
return Promise.reject(new Error('not available'));
return this.fileService.resolveContent(changelogUrl, { encoding: 'utf8' }).then(content => content.value);
}
get dependencies(): string[] {
......@@ -391,7 +384,8 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
@IProgressService2 private readonly progressService: IProgressService2,
@IExtensionService private readonly runtimeExtensionService: IExtensionService,
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
@IStorageService private readonly storageService: IStorageService
@IStorageService private readonly storageService: IStorageService,
@IFileService private readonly fileService: IFileService
) {
this.stateProvider = ext => this.getExtensionState(ext);
......@@ -443,7 +437,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
const locals = groupById[getGalleryExtensionIdFromLocal(local)];
locals.splice(locals.indexOf(local), 1);
locals.splice(0, 0, local);
const extension = installedById[local.identifier.id] || new Extension(this.galleryService, this.stateProvider, locals, undefined, this.telemetryService, this.logService);
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;
......@@ -561,7 +555,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
this.syncLocalWithGalleryExtension(result, gallery);
}
} else {
result = new Extension(this.galleryService, this.stateProvider, [], gallery, this.telemetryService, this.logService);
result = new Extension(this.galleryService, this.stateProvider, [], gallery, this.telemetryService, this.logService, this.fileService);
}
if (maliciousExtensionSet.has(result.identifier.id)) {
......@@ -920,7 +914,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
let extension = this.installed.filter(e => areSameExtensions(e.identifier, gallery.identifier))[0];
if (!extension) {
extension = new Extension(this.galleryService, this.stateProvider, [], gallery, this.telemetryService, this.logService);
extension = new Extension(this.galleryService, this.stateProvider, [], gallery, this.telemetryService, this.logService, this.fileService);
}
this.installing.push(extension);
......@@ -931,7 +925,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
private onDidInstallExtension(event: DidInstallExtensionEvent): void {
const { local, zipPath, error, gallery } = event;
const installingExtension = gallery ? this.installing.filter(e => areSameExtensions(e.identifier, gallery.identifier))[0] : null;
let extension: Extension | undefined = installingExtension ? installingExtension : zipPath ? new Extension(this.galleryService, this.stateProvider, local ? [local] : [], undefined, this.telemetryService, this.logService) : undefined;
let extension: Extension | undefined = installingExtension ? installingExtension : zipPath ? new Extension(this.galleryService, this.stateProvider, local ? [local] : [], undefined, this.telemetryService, this.logService, this.fileService) : undefined;
if (extension) {
this.installing = installingExtension ? this.installing.filter(e => e !== installingExtension) : this.installing;
if (local) {
......
......@@ -9,9 +9,7 @@ import { CharCode } from 'vs/base/common/charCode';
import * as errors from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { MarshalledObject } from 'vs/base/common/marshalling';
import { URI } from 'vs/base/common/uri';
import { IURITransformer } from 'vs/base/common/uriIpc';
import { IURITransformer, transformIncomingURIs } from 'vs/base/common/uriIpc';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc';
import { LazyPromise } from 'vs/workbench/services/extensions/node/lazyPromise';
import { IRPCProtocol, ProxyIdentifier, getStringIdentifierForProxy } from 'vs/workbench/services/extensions/node/proxyIdentifier';
......@@ -40,75 +38,6 @@ function createURIReplacer(transformer: IURITransformer | null): JSONStringifyRe
};
}
function _transformOutgoingURIs(obj: any, transformer: IURITransformer, depth: number): any {
if (!obj || depth > 200) {
return null;
}
if (typeof obj === 'object') {
if (obj instanceof URI) {
return transformer.transformOutgoing(obj);
}
// walk object (or array)
for (let key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
const r = _transformOutgoingURIs(obj[key], transformer, depth + 1);
if (r !== null) {
obj[key] = r;
}
}
}
}
return null;
}
export function transformOutgoingURIs<T>(obj: T, transformer: IURITransformer): T {
const result = _transformOutgoingURIs(obj, transformer, 0);
if (result === null) {
// no change
return obj;
}
return result;
}
function _transformIncomingURIs(obj: any, transformer: IURITransformer, depth: number): any {
if (!obj || depth > 200) {
return null;
}
if (typeof obj === 'object') {
if ((<MarshalledObject>obj).$mid === 1) {
return transformer.transformIncoming(obj);
}
// walk object (or array)
for (let key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
const r = _transformIncomingURIs(obj[key], transformer, depth + 1);
if (r !== null) {
obj[key] = r;
}
}
}
}
return null;
}
function transformIncomingURIs<T>(obj: T, transformer: IURITransformer): T {
const result = _transformIncomingURIs(obj, transformer, 0);
if (result === null) {
// no change
return obj;
}
return result;
}
export const enum RequestInitiator {
LocalSide = 0,
OtherSide = 1
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册