Skip to content

Commit

Permalink
Added extensionDependency automatically downloading. Fixes: #4504
Browse files Browse the repository at this point in the history
Signed-off-by: Josh Pinkney <joshpinkney@gmail.com>
  • Loading branch information
JPinkney committed Jun 6, 2019
1 parent 92cfe9a commit e0aedde
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 7 deletions.
3 changes: 2 additions & 1 deletion packages/plugin-ext-vscode/src/node/scanner-vscode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ export class VsCodePluginScanner extends TheiaPluginScanner implements PluginSca
},
entryPoint: {
backend: plugin.main
}
},
extensionDependencies: plugin.extensionDependencies
};
result.contributes = this.readContributions(plugin);
return result;
Expand Down
11 changes: 11 additions & 0 deletions packages/plugin-ext/src/common/plugin-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export interface PluginPackage {
description: string;
contributes?: PluginPackageContribution;
packagePath: string;
extensionDependencies?: string[];
}
export namespace PluginPackage {
export function toPluginUrl(pck: PluginPackage, relativePath: string): string {
Expand Down Expand Up @@ -312,6 +313,13 @@ export interface PluginDeployerEntry {
accept(...types: PluginDeployerEntryType[]): void;

hasError(): boolean;

/**
* For establishing dependencies that have to be
* installed before this extension can be
*/
getDependencies(): string[];
setDependencies(dependencies: string[]): void;
}

export interface PluginDeployerFileHandlerContext {
Expand Down Expand Up @@ -347,6 +355,7 @@ export interface PluginModel {
backend?: string;
};
contributes?: PluginContribution;
extensionDependencies?: string[];
}

/**
Expand Down Expand Up @@ -575,6 +584,8 @@ export const PluginDeployerHandler = Symbol('PluginDeployerHandler');
export interface PluginDeployerHandler {
deployFrontendPlugins(frontendPlugins: PluginDeployerEntry[]): Promise<void>;
deployBackendPlugins(backendPlugins: PluginDeployerEntry[]): Promise<void>;

readDeployDependencies(pluginsToBeInstalled: PluginDeployerEntry[]): Promise<PluginDeployerEntry[]>
}

export const HostedPluginServer = Symbol('HostedPluginServer');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
return this.currentBackendPluginsMetadata;
}

async readDeployDependencies(pluginsToBeInstalled: PluginDeployerEntry[]): Promise<PluginDeployerEntry[]> {
for (const plugin of pluginsToBeInstalled) {
const metadata = await this.reader.getPluginMetadata(plugin.path());
if (metadata) {
if (metadata.model.extensionDependencies) {
const appendedExtensionID = metadata.model.extensionDependencies.map(extensionID => 'vscode:extension/' + extensionID);
plugin.setDependencies(appendedExtensionID);
}
}
}
return pluginsToBeInstalled;
}

async deployFrontendPlugins(frontendPlugins: PluginDeployerEntry[]): Promise<void> {
for (const plugin of frontendPlugins) {
const metadata = await this.reader.getPluginMetadata(plugin.path());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ export class TheiaPluginScanner implements PluginScanner {
entryPoint: {
frontend: plugin.theiaPlugin!.frontend,
backend: plugin.theiaPlugin!.backend
}
},
extensionDependencies: plugin.extensionDependencies
};
result.contributes = this.readContributions(plugin);
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import * as fs from 'fs';

export class PluginDeployerEntryImpl implements PluginDeployerEntry {

private _dependencies: string[] = [];

private initPath: string;

private currentPath: string;
Expand Down Expand Up @@ -108,4 +110,11 @@ export class PluginDeployerEntryImpl implements PluginDeployerEntry {
return this.resolvedByName;
}

getDependencies(): string[] {
return this._dependencies;
}

setDependencies(dependencies: string[]): void {
this._dependencies = dependencies;
}
}
55 changes: 50 additions & 5 deletions packages/plugin-ext/src/main/node/plugin-deployer-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class PluginDeployerImpl implements PluginDeployer {
/**
* Deployer entries.
*/
private pluginDeployerEntries: PluginDeployerEntry[];
private pluginDeployerEntries: PluginDeployerEntry[] = [];

/**
* Inject all plugin resolvers found at runtime.
Expand All @@ -68,6 +68,11 @@ export class PluginDeployerImpl implements PluginDeployer {
@optional() @multiInject(PluginDeployerDirectoryHandler)
private pluginDeployerDirectoryHandlers: PluginDeployerDirectoryHandler[];

/**
* Set of extensions that are set to install
*/
private toInstall = new Set();

public start(): void {
this.logger.debug('Starting the deployer with the list of resolvers', this.pluginResolvers);
this.doStart();
Expand Down Expand Up @@ -114,20 +119,59 @@ export class PluginDeployerImpl implements PluginDeployer {
return Promise.resolve();
}

protected async deployMultipleEntries(pluginEntries: string[]): Promise<void> {
protected async download(pluginEntries: string[]): Promise<PluginDeployerEntry[]> {
// resolve plugins
this.pluginDeployerEntries = await this.resolvePlugins(pluginEntries);
const newlyResolvedPlugins = await this.resolvePlugins(pluginEntries);
this.pluginDeployerEntries.unshift(...newlyResolvedPlugins);

// now that we have plugins check if we have File Handler for them
await this.applyFileHandlers();

// ok now ask for directory handlers
await this.applyDirectoryFileHandlers();

await this.deployPlugins();
return newlyResolvedPlugins;
}

/**
* Gather all the extensions and the dependencies of those extensions that you
* want to install
*/
protected async gatherDeployDependencies(pluginEntries: string[]): Promise<void> {

if (pluginEntries.length === 0) {
return Promise.resolve();
}

for (const plugEntry of pluginEntries) {
this.toInstall.add(plugEntry);
}

const resolvedPlugins = await this.download(pluginEntries);

// So now once this is resolved we know the dependencies
const pluginDependencies = await this.pluginDeployerHandler.readDeployDependencies(resolvedPlugins);
for (const plug of pluginDependencies) {
const shouldInstall = [];

// Only gather dependencies that aren't set to install already
for (const plugEntry of plug.getDependencies()) {
if (!this.toInstall.has(plugEntry)) {
shouldInstall.push(plugEntry);
}
}
await this.gatherDeployDependencies(shouldInstall);
}
return Promise.resolve();
}

protected async deployMultipleEntries(pluginEntries: string[]): Promise<void> {

await this.gatherDeployDependencies(pluginEntries);

await this.deployPlugins();

return Promise.resolve();
}

/**
Expand Down Expand Up @@ -155,6 +199,8 @@ export class PluginDeployerImpl implements PluginDeployer {
this.pluginDeployerHandler.deployBackendPlugins(acceptedBackendPlugins),
this.pluginDeployerHandler.deployFrontendPlugins(acceptedFrontendPlugins)
]);
this.pluginDeployerEntries = [];
this.toInstall.clear();
this.onDidDeployEmitter.fire(undefined);
}

Expand Down Expand Up @@ -215,7 +261,6 @@ export class PluginDeployerImpl implements PluginDeployer {
const context = new PluginDeployerResolverContextImpl(foundPluginResolver, pluginId);

await foundPluginResolver.resolve(context);

context.getPlugins().forEach(entry => pluginDeployerEntries.push(entry));
} else {
// log it for now
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { PluginDeployerEntryImpl } from './plugin-deployer-entry-impl';
@injectable()
export class ProxyPluginDeployerEntry<T> implements PluginDeployerEntry {

private _dependencies: string[] = [];
private readonly deployerName: string;

constructor(readonly deployer: T, readonly delegate: PluginDeployerEntryImpl) {
Expand Down Expand Up @@ -76,5 +77,12 @@ export class ProxyPluginDeployerEntry<T> implements PluginDeployerEntry {
resolvedBy(): string {
return this.delegate.resolvedBy();
}
getDependencies(): string[] {
return this._dependencies;
}

setDependencies(dependencies: string[]): void {
this._dependencies = dependencies;
}

}

0 comments on commit e0aedde

Please sign in to comment.