Skip to content

Commit

Permalink
plugin-ext: lookup plugins in user home dir
Browse files Browse the repository at this point in the history
Allow configuring plugin locations via backend configuration, and look
into the user home by default.

Signed-off-by: Paul Maréchal <[email protected]>
  • Loading branch information
paul-marechal committed Feb 5, 2020
1 parent 8cf1dec commit 3385a94
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Change Log

## v0.16.0

- [plugin-ext] Plugins are now looked up in `$HOME/.theia/extensions` by default.
- [plugin-ext] You can specify lookup paths for plugins from the `BackendApplicationConfig.plugins` entry.

## v0.15.0

- [application-manager] added config to disable reloading windows [#6981](https://github.com/eclipse-theia/theia/pull/6981)
Expand Down
8 changes: 8 additions & 0 deletions packages/plugin-ext/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Theia - Theia - Plugin API

You can configure paths to folders containing plugins:

- Environment variables: `DEFAULT_THEIA_PLUGINS`, `THEIA_PLUGINS`. Use comma-separated paths.
- CLI argument: `--plugins`. Use comma-separated paths.
- Backend configuration: `plugins` entry. Array or single string.

Use the `local-dir:` file scheme to refer to paths on your local disk (where the backend is hosted).

See [here](https://www.theia-ide.org/doc/index.html) for a detailed documentation.

## License
Expand Down
41 changes: 39 additions & 2 deletions packages/plugin-ext/src/main/node/plugin-deployer-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { injectable, optional, multiInject, inject } from 'inversify';
import { PluginPathsService } from '../common/plugin-paths-protocol';
import {
PluginDeployerResolver, PluginDeployerFileHandler, PluginDeployerDirectoryHandler,
PluginDeployerEntry, PluginDeployer, PluginDeployerResolverInit, PluginDeployerFileHandlerContext,
Expand All @@ -30,9 +31,11 @@ import {
import { ProxyPluginDeployerEntry } from './plugin-deployer-proxy-entry-impl';
import { PluginDeployerFileHandlerContextImpl } from './plugin-deployer-file-handler-context-impl';
import { PluginDeployerDirectoryHandlerContextImpl } from './plugin-deployer-directory-handler-context-impl';
import { BackendApplicationConfigProvider } from '@theia/core/lib/node/backend-application-config-provider';
import { ILogger, Emitter } from '@theia/core';
import { PluginCliContribution } from './plugin-cli-contribution';
import { performance } from 'perf_hooks';
import * as path from 'path';

@injectable()
export class PluginDeployerImpl implements PluginDeployer {
Expand All @@ -49,6 +52,9 @@ export class PluginDeployerImpl implements PluginDeployer {
@inject(PluginCliContribution)
protected readonly cliContribution: PluginCliContribution;

@inject(PluginPathsService)
protected readonly pluginPathsService: PluginPathsService;

/**
* Inject all plugin resolvers found at runtime.
*/
Expand Down Expand Up @@ -91,24 +97,55 @@ export class PluginDeployerImpl implements PluginDeployer {

// check THEIA_DEFAULT_PLUGINS or THEIA_PLUGINS env var
const defaultPluginsValue = process.env.THEIA_DEFAULT_PLUGINS || undefined;
const pluginsValueViaConfig = BackendApplicationConfigProvider.get().plugins;
const pluginsValue = process.env.THEIA_PLUGINS || undefined;
// check the `--plugins` CLI option
const defaultPluginsValueViaCli = this.cliContribution.localDir();

this.logger.debug('Found the list of default plugins ID on env:', defaultPluginsValue);
this.logger.debug('Found the list of plugins ID from config:', pluginsValueViaConfig);
this.logger.debug('Found the list of plugins ID on env:', pluginsValue);
this.logger.debug('Found the list of default plugins ID from CLI:', defaultPluginsValueViaCli);

// transform it to array
const defaultPluginIdList = defaultPluginsValue ? defaultPluginsValue.split(',') : [];
const pluginIdList = pluginsValue ? pluginsValue.split(',') : [];
const pluginsList = defaultPluginIdList.concat(pluginIdList).concat(defaultPluginsValueViaCli ? defaultPluginsValueViaCli.split(',') : []);
const pluginIdListViaConfig = await this.validatePluginIdListViaConfig(pluginsValueViaConfig);
const pluginIdListViaCli = defaultPluginsValueViaCli ? defaultPluginsValueViaCli.split(',') : [];
const pluginsList = await this.resolvePluginIdList([pluginIdListViaCli, pluginIdList, pluginIdListViaConfig, defaultPluginIdList]);

const startDeployTime = performance.now();
await this.deployMultipleEntries(pluginsList);
this.logMeasurement('Deploy plugins list', startDeployTime);
}

/**
* @param plugins BackendApplicationConfig.plugins
*/
protected async validatePluginIdListViaConfig(plugins: any): Promise<string[]> {
if (!plugins) {
return [];
} else if (typeof plugins === 'string') {
return [plugins];
} else if (Array.isArray(plugins)) {
return plugins;
} else {
throw new TypeError(`expected pluginFolder to be "string | string[]", got "${typeof plugins}"`);
}
}

/**
* Puts together user-configurable and non-user-configurable plugin paths.
*
* @param pluginIdLists
*/
protected async resolvePluginIdList(pluginIdLists: string[][]): Promise<string[]> {
return ([] as string[]).concat(
[`local-dir:${path.join(await this.pluginPathsService.getTheiaDirPath(), 'extensions')}`],
...pluginIdLists
);
}

public async deploy(pluginEntry: string): Promise<void> {
const startDeployTime = performance.now();
await this.deployMultipleEntries([pluginEntry]);
Expand All @@ -121,7 +158,7 @@ export class PluginDeployerImpl implements PluginDeployer {

let queue = [...pluginEntries];
while (queue.length) {
const dependenciesChunk: Array< Map<string, string>> = [];
const dependenciesChunk: Array<Map<string, string>> = [];
const workload: string[] = [];
while (queue.length) {
const current = queue.shift()!;
Expand Down

0 comments on commit 3385a94

Please sign in to comment.