Skip to content

Commit

Permalink
[plugin] fix #3976: resolve VS Code from sources
Browse files Browse the repository at this point in the history
Signed-off-by: Anton Kosyakov <anton.kosyakov@typefox.io>
  • Loading branch information
akosyakov committed Jan 10, 2019
1 parent 0a6abc4 commit ed0a7d5
Showing 1 changed file with 42 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,73 +14,66 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import * as fs from 'fs';
import * as path from 'path';
import { injectable } from 'inversify';
import { RecursivePartial } from '@theia/core';
import {
PluginDeployerDirectoryHandler,
PluginDeployerEntry, PluginPackage, PluginDeployerDirectoryHandlerContext,
PluginDeployerEntryType
PluginDeployerEntry, PluginDeployerDirectoryHandlerContext,
PluginDeployerEntryType, PluginPackage
} from '@theia/plugin-ext';
import { injectable } from 'inversify';
import * as fs from 'fs';
import * as path from 'path';

@injectable()
export class PluginVsCodeDirectoryHandler implements PluginDeployerDirectoryHandler {

accept(resolvedPlugin: PluginDeployerEntry): boolean {

console.log('PluginVsCodeDirectoryHandler: accepting plugin with path', resolvedPlugin.path());
accept(plugin: PluginDeployerEntry): boolean {
console.debug(`Resolving "${plugin.id()}" as a VS Code extension...`);
return this.resolvePackage(plugin) || this.resolveFromSources(plugin) || this.resolveFromVSIX(plugin);
}

// handle only directories
if (resolvedPlugin.isFile()) {
return false;
}
async handle(context: PluginDeployerDirectoryHandlerContext): Promise<void> {
context.pluginEntry().accept(PluginDeployerEntryType.BACKEND);
}

// is there a extension.vsixmanifest and extension folder
const extensionVsixManifestPath = path.resolve(resolvedPlugin.path(), 'extension.vsixmanifest');
const existsExtensionVsixManifest: boolean = fs.existsSync(extensionVsixManifestPath);
if (!existsExtensionVsixManifest) {
return false;
}
protected resolveFromSources(plugin: PluginDeployerEntry): boolean {
const pluginPath = plugin.path();
return this.resolvePackage(plugin, { pluginPath, pck: this.requirePackage(pluginPath) });
}

const extensionPath = path.resolve(resolvedPlugin.path(), 'extension');
const existsExtension: boolean = fs.existsSync(extensionPath);
if (!existsExtension) {
protected resolveFromVSIX(plugin: PluginDeployerEntry): boolean {
if (!fs.existsSync(path.join(plugin.path(), 'extension.vsixmanifest'))) {
return false;
}
const pluginPath = path.join(plugin.path(), 'extension');
return this.resolvePackage(plugin, { pluginPath, pck: this.requirePackage(pluginPath) });
}

// is there a package.json ?
const packageJsonPath = path.resolve(extensionPath, 'package.json');
const existsPackageJson: boolean = fs.existsSync(packageJsonPath);
if (!existsPackageJson) {
protected resolvePackage(plugin: PluginDeployerEntry, options?: {
pluginPath: string
pck?: RecursivePartial<PluginPackage>
}): boolean {
const { pluginPath, pck } = options || {
pluginPath: plugin.path(),
pck: plugin.getValue('package.json')
};
if (!pck || !pck.name || !pck.version || !pck.engines || !pck.engines.vscode) {
return false;
}

let packageJson: PluginPackage = resolvedPlugin.getValue('package.json');
if (!packageJson) {
packageJson = require(packageJsonPath);
resolvedPlugin.storeValue('package.json', packageJson);
}

if (!packageJson.engines) {
return false;
if (options) {
plugin.storeValue('package.json', pck);
plugin.updatePath(pluginPath);
}
console.log(`Resolved "${plugin.id()}" to a VS Code extension "${pck.name}@${pck.version}" with engines:`, pck.engines);
return true;
}

if (packageJson.engines && packageJson.engines.vscode) {
console.log('accepting packagejson with engines', packageJson.engines);
return true;
protected requirePackage(pluginPath: string): PluginPackage | undefined {
try {
return require(path.join(pluginPath, 'package.json'));
} catch {
return undefined;
}

return false;

}

// tslint:disable-next-line:no-any
handle(context: PluginDeployerDirectoryHandlerContext): Promise<any> {
context.pluginEntry().accept(PluginDeployerEntryType.BACKEND);

const extensionPath = path.resolve(context.pluginEntry().path(), 'extension');
context.pluginEntry().updatePath(extensionPath);

return Promise.resolve(true);
}
}

0 comments on commit ed0a7d5

Please sign in to comment.