@theia/plugin-ext 1.27.0-next.8 → 1.28.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/connection.d.ts +3 -3
- package/lib/common/connection.d.ts.map +1 -1
- package/lib/common/connection.js +0 -1
- package/lib/common/connection.js.map +1 -1
- package/lib/common/plugin-api-rpc.d.ts +18 -8
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/common/plugin-identifiers.d.ts +41 -0
- package/lib/common/plugin-identifiers.d.ts.map +1 -0
- package/lib/common/plugin-identifiers.js +81 -0
- package/lib/common/plugin-identifiers.js.map +1 -0
- package/lib/common/plugin-protocol.d.ts +50 -11
- package/lib/common/plugin-protocol.d.ts.map +1 -1
- package/lib/common/plugin-protocol.js +3 -1
- package/lib/common/plugin-protocol.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts +2 -2
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +26 -18
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/browser/worker/debug-stub.d.ts +1 -1
- package/lib/hosted/browser/worker/debug-stub.d.ts.map +1 -1
- package/lib/hosted/browser/worker/debug-stub.js +2 -2
- package/lib/hosted/browser/worker/debug-stub.js.map +1 -1
- package/lib/hosted/browser/worker/plugin-manifest-loader.d.ts.map +1 -1
- package/lib/hosted/browser/worker/plugin-manifest-loader.js +4 -1
- package/lib/hosted/browser/worker/plugin-manifest-loader.js.map +1 -1
- package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts +17 -9
- package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts.map +1 -1
- package/lib/hosted/node/hosted-plugin-deployer-handler.js +99 -18
- package/lib/hosted/node/hosted-plugin-deployer-handler.js.map +1 -1
- package/lib/hosted/node/hosted-plugin-localization-service.d.ts.map +1 -1
- package/lib/hosted/node/hosted-plugin-localization-service.js +2 -4
- package/lib/hosted/node/hosted-plugin-localization-service.js.map +1 -1
- package/lib/hosted/node/hosted-plugin-process.d.ts +2 -2
- package/lib/hosted/node/hosted-plugin-process.d.ts.map +1 -1
- package/lib/hosted/node/hosted-plugin-process.js.map +1 -1
- package/lib/hosted/node/hosted-plugin.d.ts +2 -2
- package/lib/hosted/node/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/node/hosted-plugin.js.map +1 -1
- package/lib/hosted/node/metadata-scanner.d.ts +3 -2
- package/lib/hosted/node/metadata-scanner.d.ts.map +1 -1
- package/lib/hosted/node/metadata-scanner.js +8 -3
- package/lib/hosted/node/metadata-scanner.js.map +1 -1
- package/lib/hosted/node/plugin-host-rpc.js +2 -2
- package/lib/hosted/node/plugin-host-rpc.js.map +1 -1
- package/lib/hosted/node/plugin-manifest-loader.d.ts.map +1 -1
- package/lib/hosted/node/plugin-manifest-loader.js +3 -0
- package/lib/hosted/node/plugin-manifest-loader.js.map +1 -1
- package/lib/hosted/node/plugin-service.d.ts +18 -4
- package/lib/hosted/node/plugin-service.d.ts.map +1 -1
- package/lib/hosted/node/plugin-service.js +73 -18
- package/lib/hosted/node/plugin-service.js.map +1 -1
- package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
- package/lib/hosted/node/scanners/scanner-theia.js +6 -3
- package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
- package/lib/main/browser/custom-editors/custom-editor-opener.d.ts.map +1 -1
- package/lib/main/browser/custom-editors/custom-editor-opener.js +2 -2
- package/lib/main/browser/custom-editors/custom-editor-opener.js.map +1 -1
- package/lib/main/browser/debug/plugin-debug-session-factory.d.ts +3 -3
- package/lib/main/browser/debug/plugin-debug-session-factory.d.ts.map +1 -1
- package/lib/main/browser/debug/plugin-debug-session-factory.js.map +1 -1
- package/lib/main/browser/documents-main.d.ts +1 -2
- package/lib/main/browser/documents-main.d.ts.map +1 -1
- package/lib/main/browser/documents-main.js +26 -6
- package/lib/main/browser/documents-main.js.map +1 -1
- package/lib/main/browser/editors-and-documents-main.d.ts +2 -0
- package/lib/main/browser/editors-and-documents-main.d.ts.map +1 -1
- package/lib/main/browser/editors-and-documents-main.js +14 -2
- package/lib/main/browser/editors-and-documents-main.js.map +1 -1
- package/lib/main/browser/languages-main.d.ts.map +1 -1
- package/lib/main/browser/languages-main.js +2 -1
- package/lib/main/browser/languages-main.js.map +1 -1
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +5 -4
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/plugin-contribution-handler.d.ts +2 -0
- package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
- package/lib/main/browser/plugin-contribution-handler.js +36 -1
- package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
- package/lib/main/browser/plugin-shared-style.d.ts +4 -2
- package/lib/main/browser/plugin-shared-style.d.ts.map +1 -1
- package/lib/main/browser/plugin-shared-style.js +15 -4
- package/lib/main/browser/plugin-shared-style.js.map +1 -1
- package/lib/main/browser/text-editors-main.d.ts +6 -3
- package/lib/main/browser/text-editors-main.d.ts.map +1 -1
- package/lib/main/browser/text-editors-main.js +8 -1
- package/lib/main/browser/text-editors-main.js.map +1 -1
- package/lib/main/browser/theming-main.d.ts +2 -1
- package/lib/main/browser/theming-main.d.ts.map +1 -1
- package/lib/main/browser/theming-main.js +3 -6
- package/lib/main/browser/theming-main.js.map +1 -1
- package/lib/main/browser/view/plugin-tree-view-node-label-provider.d.ts.map +1 -1
- package/lib/main/browser/view/plugin-tree-view-node-label-provider.js +7 -5
- package/lib/main/browser/view/plugin-tree-view-node-label-provider.js.map +1 -1
- package/lib/main/browser/view/plugin-view-registry.d.ts +1 -1
- package/lib/main/browser/view/plugin-view-registry.d.ts.map +1 -1
- package/lib/main/browser/view/plugin-view-registry.js +11 -6
- package/lib/main/browser/view/plugin-view-registry.js.map +1 -1
- package/lib/main/browser/view/tree-view-widget.d.ts +10 -5
- package/lib/main/browser/view/tree-view-widget.d.ts.map +1 -1
- package/lib/main/browser/view/tree-view-widget.js +40 -14
- package/lib/main/browser/view/tree-view-widget.js.map +1 -1
- package/lib/main/browser/webview/webview-theme-data-provider.d.ts +3 -1
- package/lib/main/browser/webview/webview-theme-data-provider.d.ts.map +1 -1
- package/lib/main/browser/webview/webview-theme-data-provider.js +5 -1
- package/lib/main/browser/webview/webview-theme-data-provider.js.map +1 -1
- package/lib/main/node/handlers/plugin-theia-directory-handler.d.ts +6 -1
- package/lib/main/node/handlers/plugin-theia-directory-handler.d.ts.map +1 -1
- package/lib/main/node/handlers/plugin-theia-directory-handler.js +61 -20
- package/lib/main/node/handlers/plugin-theia-directory-handler.js.map +1 -1
- package/lib/main/node/handlers/plugin-theia-file-handler.d.ts +4 -0
- package/lib/main/node/handlers/plugin-theia-file-handler.d.ts.map +1 -1
- package/lib/main/node/handlers/plugin-theia-file-handler.js +26 -4
- package/lib/main/node/handlers/plugin-theia-file-handler.js.map +1 -1
- package/lib/main/node/plugin-cli-contribution.d.ts +3 -0
- package/lib/main/node/plugin-cli-contribution.d.ts.map +1 -1
- package/lib/main/node/plugin-cli-contribution.js +13 -0
- package/lib/main/node/plugin-cli-contribution.js.map +1 -1
- package/lib/main/node/plugin-deployer-directory-handler-context-impl.d.ts +1 -0
- package/lib/main/node/plugin-deployer-directory-handler-context-impl.d.ts.map +1 -1
- package/lib/main/node/plugin-deployer-directory-handler-context-impl.js +17 -0
- package/lib/main/node/plugin-deployer-directory-handler-context-impl.js.map +1 -1
- package/lib/main/node/plugin-deployer-file-handler-context-impl.d.ts.map +1 -1
- package/lib/main/node/plugin-deployer-file-handler-context-impl.js +0 -1
- package/lib/main/node/plugin-deployer-file-handler-context-impl.js.map +1 -1
- package/lib/main/node/plugin-deployer-impl.d.ts +10 -7
- package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
- package/lib/main/node/plugin-deployer-impl.js +84 -38
- package/lib/main/node/plugin-deployer-impl.js.map +1 -1
- package/lib/main/node/plugin-ext-backend-module.d.ts.map +1 -1
- package/lib/main/node/plugin-ext-backend-module.js +2 -0
- package/lib/main/node/plugin-ext-backend-module.js.map +1 -1
- package/lib/main/node/plugin-server-handler.d.ts +5 -4
- package/lib/main/node/plugin-server-handler.d.ts.map +1 -1
- package/lib/main/node/plugin-server-handler.js +12 -5
- package/lib/main/node/plugin-server-handler.js.map +1 -1
- package/lib/main/node/plugin-uninstallation-manager.d.ts +15 -0
- package/lib/main/node/plugin-uninstallation-manager.d.ts.map +1 -0
- package/lib/main/node/plugin-uninstallation-manager.js +85 -0
- package/lib/main/node/plugin-uninstallation-manager.js.map +1 -0
- package/lib/plugin/{node/debug/debug.d.ts → debug/debug-ext.d.ts} +15 -13
- package/lib/plugin/debug/debug-ext.d.ts.map +1 -0
- package/lib/plugin/{node/debug/debug.js → debug/debug-ext.js} +17 -51
- package/lib/plugin/debug/debug-ext.js.map +1 -0
- package/lib/plugin/debug/plugin-debug-adapter-creator.d.ts +11 -0
- package/lib/plugin/debug/plugin-debug-adapter-creator.d.ts.map +1 -0
- package/lib/plugin/debug/plugin-debug-adapter-creator.js +42 -0
- package/lib/plugin/debug/plugin-debug-adapter-creator.js.map +1 -0
- package/lib/plugin/{node/debug → debug}/plugin-debug-adapter-session.d.ts +4 -4
- package/lib/plugin/debug/plugin-debug-adapter-session.d.ts.map +1 -0
- package/lib/plugin/{node/debug → debug}/plugin-debug-adapter-session.js +1 -1
- package/lib/plugin/debug/plugin-debug-adapter-session.js.map +1 -0
- package/lib/plugin/{node/debug → debug}/plugin-debug-adapter-tracker.d.ts +0 -0
- package/lib/plugin/debug/plugin-debug-adapter-tracker.d.ts.map +1 -0
- package/lib/plugin/{node/debug → debug}/plugin-debug-adapter-tracker.js +0 -0
- package/lib/plugin/debug/plugin-debug-adapter-tracker.js.map +1 -0
- package/lib/plugin/languages-utils.d.ts.map +1 -1
- package/lib/plugin/languages-utils.js +3 -2
- package/lib/plugin/languages-utils.js.map +1 -1
- package/lib/plugin/node/debug/plugin-node-debug-adapter-creator.d.ts +18 -0
- package/lib/plugin/node/debug/plugin-node-debug-adapter-creator.d.ts.map +1 -0
- package/lib/plugin/node/debug/plugin-node-debug-adapter-creator.js +155 -0
- package/lib/plugin/node/debug/plugin-node-debug-adapter-creator.js.map +1 -0
- package/lib/plugin/plugin-context.d.ts +1 -1
- package/lib/plugin/plugin-context.d.ts.map +1 -1
- package/lib/plugin/plugin-context.js +1 -2
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/plugin/plugin-manager.js +5 -9
- package/lib/plugin/plugin-manager.js.map +1 -1
- package/lib/plugin/text-editor.d.ts +2 -0
- package/lib/plugin/text-editor.d.ts.map +1 -1
- package/lib/plugin/text-editor.js +9 -0
- package/lib/plugin/text-editor.js.map +1 -1
- package/lib/plugin/theming.d.ts +1 -1
- package/lib/plugin/theming.d.ts.map +1 -1
- package/lib/plugin/tree/tree-views.d.ts +1 -0
- package/lib/plugin/tree/tree-views.d.ts.map +1 -1
- package/lib/plugin/tree/tree-views.js +10 -9
- package/lib/plugin/tree/tree-views.js.map +1 -1
- package/lib/plugin/types-impl.d.ts +1 -0
- package/lib/plugin/types-impl.d.ts.map +1 -1
- package/lib/plugin/types-impl.js +3 -2
- package/lib/plugin/types-impl.js.map +1 -1
- package/package.json +26 -25
- package/src/common/connection.ts +3 -4
- package/src/common/plugin-api-rpc.ts +20 -12
- package/src/common/plugin-identifiers.ts +84 -0
- package/src/common/plugin-protocol.ts +57 -12
- package/src/hosted/browser/hosted-plugin.ts +28 -21
- package/src/hosted/browser/worker/debug-stub.ts +1 -1
- package/src/hosted/browser/worker/plugin-manifest-loader.ts +4 -2
- package/src/hosted/node/hosted-plugin-deployer-handler.ts +109 -28
- package/src/hosted/node/hosted-plugin-localization-service.ts +4 -6
- package/src/hosted/node/hosted-plugin-process.ts +4 -4
- package/src/hosted/node/hosted-plugin.ts +2 -2
- package/src/hosted/node/metadata-scanner.ts +8 -6
- package/src/hosted/node/plugin-host-rpc.ts +2 -2
- package/src/hosted/node/plugin-manifest-loader.ts +2 -0
- package/src/hosted/node/plugin-service.ts +79 -23
- package/src/hosted/node/scanners/scanner-theia.ts +7 -4
- package/src/main/browser/custom-editors/custom-editor-opener.tsx +2 -2
- package/src/main/browser/debug/plugin-debug-session-factory.ts +2 -2
- package/src/main/browser/documents-main.ts +26 -8
- package/src/main/browser/editors-and-documents-main.ts +16 -2
- package/src/main/browser/languages-main.ts +2 -1
- package/src/main/browser/main-context.ts +4 -3
- package/src/main/browser/plugin-contribution-handler.ts +41 -3
- package/src/main/browser/plugin-icon-theme-service.ts +1 -1
- package/src/main/browser/plugin-shared-style.ts +9 -5
- package/src/main/browser/text-editors-main.ts +12 -2
- package/src/main/browser/theming-main.ts +3 -7
- package/src/main/browser/view/plugin-tree-view-node-label-provider.ts +7 -5
- package/src/main/browser/view/plugin-view-registry.ts +12 -7
- package/src/main/browser/view/tree-view-widget.tsx +45 -17
- package/src/main/browser/webview/webview-theme-data-provider.ts +7 -10
- package/src/main/node/handlers/plugin-theia-directory-handler.ts +56 -28
- package/src/main/node/handlers/plugin-theia-file-handler.ts +26 -4
- package/src/main/node/plugin-cli-contribution.ts +12 -0
- package/src/main/node/plugin-deployer-directory-handler-context-impl.ts +17 -1
- package/src/main/node/plugin-deployer-file-handler-context-impl.ts +0 -1
- package/src/main/node/plugin-deployer-impl.ts +88 -41
- package/src/main/node/plugin-ext-backend-module.ts +3 -0
- package/src/main/node/plugin-server-handler.ts +15 -7
- package/src/main/node/plugin-uninstallation-manager.ts +74 -0
- package/src/plugin/{node/debug/debug.ts → debug/debug-ext.ts} +25 -56
- package/src/plugin/debug/plugin-debug-adapter-creator.ts +50 -0
- package/src/plugin/{node/debug → debug}/plugin-debug-adapter-session.ts +4 -4
- package/src/plugin/{node/debug → debug}/plugin-debug-adapter-tracker.ts +0 -0
- package/src/plugin/languages-utils.ts +3 -2
- package/src/plugin/node/debug/plugin-node-debug-adapter-creator.ts +167 -0
- package/src/plugin/plugin-context.ts +2 -3
- package/src/plugin/plugin-manager.ts +5 -9
- package/src/plugin/text-editor.ts +16 -5
- package/src/plugin/theming.ts +1 -1
- package/src/plugin/tree/tree-views.ts +15 -12
- package/src/plugin/types-impl.ts +1 -1
- package/lib/main/browser/custom-editors/glob.d.ts +0 -51
- package/lib/main/browser/custom-editors/glob.d.ts.map +0 -1
- package/lib/main/browser/custom-editors/glob.js +0 -593
- package/lib/main/browser/custom-editors/glob.js.map +0 -1
- package/lib/main/browser/custom-editors/paths.d.ts +0 -25
- package/lib/main/browser/custom-editors/paths.d.ts.map +0 -1
- package/lib/main/browser/custom-editors/paths.js +0 -227
- package/lib/main/browser/custom-editors/paths.js.map +0 -1
- package/lib/main/browser/editor/untitled-resource.d.ts +0 -3
- package/lib/main/browser/editor/untitled-resource.d.ts.map +0 -1
- package/lib/main/browser/editor/untitled-resource.js +0 -24
- package/lib/main/browser/editor/untitled-resource.js.map +0 -1
- package/lib/plugin/node/debug/debug.d.ts.map +0 -1
- package/lib/plugin/node/debug/debug.js.map +0 -1
- package/lib/plugin/node/debug/plugin-debug-adapter-executable-resolver.d.ts +0 -7
- package/lib/plugin/node/debug/plugin-debug-adapter-executable-resolver.d.ts.map +0 -1
- package/lib/plugin/node/debug/plugin-debug-adapter-executable-resolver.js +0 -57
- package/lib/plugin/node/debug/plugin-debug-adapter-executable-resolver.js.map +0 -1
- package/lib/plugin/node/debug/plugin-debug-adapter-session.d.ts.map +0 -1
- package/lib/plugin/node/debug/plugin-debug-adapter-session.js.map +0 -1
- package/lib/plugin/node/debug/plugin-debug-adapter-starter.d.ts +0 -15
- package/lib/plugin/node/debug/plugin-debug-adapter-starter.d.ts.map +0 -1
- package/lib/plugin/node/debug/plugin-debug-adapter-starter.js +0 -85
- package/lib/plugin/node/debug/plugin-debug-adapter-starter.js.map +0 -1
- package/lib/plugin/node/debug/plugin-debug-adapter-tracker.d.ts.map +0 -1
- package/lib/plugin/node/debug/plugin-debug-adapter-tracker.js.map +0 -1
- package/lib/plugin/node/debug/plugin-inline-debug-adapter.d.ts +0 -19
- package/lib/plugin/node/debug/plugin-inline-debug-adapter.d.ts.map +0 -1
- package/lib/plugin/node/debug/plugin-inline-debug-adapter.js +0 -45
- package/lib/plugin/node/debug/plugin-inline-debug-adapter.js.map +0 -1
- package/src/main/browser/custom-editors/glob.ts +0 -743
- package/src/main/browser/custom-editors/paths.ts +0 -250
- package/src/main/browser/editor/untitled-resource.ts +0 -18
- package/src/plugin/node/debug/plugin-debug-adapter-executable-resolver.ts +0 -58
- package/src/plugin/node/debug/plugin-debug-adapter-starter.ts +0 -86
- package/src/plugin/node/debug/plugin-inline-debug-adapter.ts +0 -47
|
@@ -14,18 +14,24 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
import * as filenamify from 'filenamify';
|
|
19
|
+
import * as fs from '@theia/core/shared/fs-extra';
|
|
20
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
21
|
+
import { FileUri } from '@theia/core/lib/node';
|
|
17
22
|
import {
|
|
18
|
-
PluginDeployerDirectoryHandler,
|
|
19
|
-
PluginDeployerEntry, PluginPackage, PluginDeployerDirectoryHandlerContext,
|
|
20
|
-
PluginDeployerEntryType
|
|
23
|
+
PluginDeployerDirectoryHandler, PluginDeployerEntry, PluginPackage, PluginDeployerDirectoryHandlerContext, PluginDeployerEntryType, PluginType, PluginIdentifiers
|
|
21
24
|
} from '../../../common/plugin-protocol';
|
|
22
|
-
import {
|
|
23
|
-
import
|
|
24
|
-
import * as path from 'path';
|
|
25
|
+
import { PluginCliContribution } from '../plugin-cli-contribution';
|
|
26
|
+
import { getTempDir } from '../temp-dir-util';
|
|
25
27
|
|
|
26
28
|
@injectable()
|
|
27
29
|
export class PluginTheiaDirectoryHandler implements PluginDeployerDirectoryHandler {
|
|
28
30
|
|
|
31
|
+
protected readonly deploymentDirectory = FileUri.create(getTempDir('theia-copied'));
|
|
32
|
+
|
|
33
|
+
@inject(PluginCliContribution) protected readonly pluginCli: PluginCliContribution;
|
|
34
|
+
|
|
29
35
|
accept(resolvedPlugin: PluginDeployerEntry): boolean {
|
|
30
36
|
|
|
31
37
|
console.log('PluginTheiaDirectoryHandler: accepting plugin with path', resolvedPlugin.path());
|
|
@@ -37,33 +43,26 @@ export class PluginTheiaDirectoryHandler implements PluginDeployerDirectoryHandl
|
|
|
37
43
|
|
|
38
44
|
// is there a package.json ?
|
|
39
45
|
const packageJsonPath = path.resolve(resolvedPlugin.path(), 'package.json');
|
|
40
|
-
const existsPackageJson: boolean = fs.existsSync(packageJsonPath);
|
|
41
|
-
if (!existsPackageJson) {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
let packageJson: PluginPackage = resolvedPlugin.getValue('package.json');
|
|
46
|
-
if (!packageJson) {
|
|
47
|
-
packageJson = fs.readJSONSync(packageJsonPath);
|
|
48
|
-
resolvedPlugin.storeValue('package.json', packageJson);
|
|
49
|
-
}
|
|
50
46
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
47
|
+
try {
|
|
48
|
+
let packageJson = resolvedPlugin.getValue<PluginPackage>('package.json');
|
|
49
|
+
if (!packageJson) {
|
|
50
|
+
packageJson = fs.readJSONSync(packageJsonPath);
|
|
51
|
+
packageJson.publisher ??= PluginIdentifiers.UNPUBLISHED;
|
|
52
|
+
resolvedPlugin.storeValue('package.json', packageJson);
|
|
53
|
+
}
|
|
58
54
|
|
|
55
|
+
if (packageJson?.engines?.theiaPlugin) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
} catch { /* Failed to read file. Fall through. */ }
|
|
59
59
|
return false;
|
|
60
|
-
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
async handle(context: PluginDeployerDirectoryHandlerContext): Promise<void> {
|
|
63
|
+
await this.copyDirectory(context);
|
|
65
64
|
const types: PluginDeployerEntryType[] = [];
|
|
66
|
-
const packageJson
|
|
65
|
+
const packageJson = context.pluginEntry().getValue<PluginPackage>('package.json');
|
|
67
66
|
if (packageJson.theiaPlugin && packageJson.theiaPlugin.backend) {
|
|
68
67
|
types.push(PluginDeployerEntryType.BACKEND);
|
|
69
68
|
}
|
|
@@ -72,6 +71,35 @@ export class PluginTheiaDirectoryHandler implements PluginDeployerDirectoryHandl
|
|
|
72
71
|
}
|
|
73
72
|
|
|
74
73
|
context.pluginEntry().accept(...types);
|
|
75
|
-
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
protected async copyDirectory(context: PluginDeployerDirectoryHandlerContext): Promise<void> {
|
|
77
|
+
if (this.pluginCli.copyUncompressedPlugins() && context.pluginEntry().type === PluginType.User) {
|
|
78
|
+
const entry = context.pluginEntry();
|
|
79
|
+
const id = entry.id();
|
|
80
|
+
const pathToRestore = entry.path();
|
|
81
|
+
const origin = entry.originalPath();
|
|
82
|
+
const targetDir = await this.getExtensionDir(context);
|
|
83
|
+
try {
|
|
84
|
+
if (fs.existsSync(targetDir) || !entry.path().startsWith(origin)) {
|
|
85
|
+
console.log(`[${id}]: already copied.`);
|
|
86
|
+
} else {
|
|
87
|
+
console.log(`[${id}]: copying to "${targetDir}"`);
|
|
88
|
+
await fs.mkdirp(FileUri.fsPath(this.deploymentDirectory));
|
|
89
|
+
await context.copy(origin, targetDir);
|
|
90
|
+
entry.updatePath(targetDir);
|
|
91
|
+
if (!this.accept(entry)) {
|
|
92
|
+
throw new Error('Unable to resolve plugin metadata after copying');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
} catch (e) {
|
|
96
|
+
console.warn(`[${id}]: Error when copying.`, e);
|
|
97
|
+
entry.updatePath(pathToRestore);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
protected async getExtensionDir(context: PluginDeployerDirectoryHandlerContext): Promise<string> {
|
|
103
|
+
return FileUri.fsPath(this.deploymentDirectory.resolve(filenamify(context.pluginEntry().id(), { replacement: '_' })));
|
|
76
104
|
}
|
|
77
105
|
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
+
import * as path from 'path';
|
|
17
18
|
import { PluginDeployerFileHandler, PluginDeployerEntry, PluginDeployerFileHandlerContext, PluginType } from '../../../common/plugin-protocol';
|
|
18
19
|
import { injectable, inject } from '@theia/core/shared/inversify';
|
|
19
20
|
import { getTempDir } from '../temp-dir-util';
|
|
@@ -21,6 +22,7 @@ import * as fs from '@theia/core/shared/fs-extra';
|
|
|
21
22
|
import * as filenamify from 'filenamify';
|
|
22
23
|
import { FileUri } from '@theia/core/lib/node/file-uri';
|
|
23
24
|
import { PluginTheiaEnvironment } from '../../common/plugin-theia-environment';
|
|
25
|
+
import URI from '@theia/core/lib/common/uri';
|
|
24
26
|
|
|
25
27
|
@injectable()
|
|
26
28
|
export class PluginTheiaFileHandler implements PluginDeployerFileHandler {
|
|
@@ -35,6 +37,7 @@ export class PluginTheiaFileHandler implements PluginDeployerFileHandler {
|
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
async handle(context: PluginDeployerFileHandlerContext): Promise<void> {
|
|
40
|
+
await this.ensureDiscoverability(context);
|
|
38
41
|
const id = context.pluginEntry().id();
|
|
39
42
|
const pluginDir = await this.getPluginDir(context);
|
|
40
43
|
console.log(`[${id}]: trying to decompress into "${pluginDir}"...`);
|
|
@@ -48,11 +51,30 @@ export class PluginTheiaFileHandler implements PluginDeployerFileHandler {
|
|
|
48
51
|
context.pluginEntry().updatePath(pluginDir);
|
|
49
52
|
}
|
|
50
53
|
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Ensures that a user-installed plugin file is transferred to the user extension folder.
|
|
56
|
+
*/
|
|
57
|
+
protected async ensureDiscoverability(context: PluginDeployerFileHandlerContext): Promise<void> {
|
|
53
58
|
if (context.pluginEntry().type === PluginType.User) {
|
|
54
|
-
|
|
59
|
+
const userExtensionsDir = await this.environment.getPluginsDirUri();
|
|
60
|
+
const currentPath = context.pluginEntry().path();
|
|
61
|
+
if (!userExtensionsDir.isEqualOrParent(new URI(currentPath)) && !userExtensionsDir.isEqualOrParent(new URI(context.pluginEntry().originalPath()))) {
|
|
62
|
+
try {
|
|
63
|
+
const newPath = FileUri.fsPath(userExtensionsDir.resolve(path.basename(currentPath)));
|
|
64
|
+
await fs.mkdirp(FileUri.fsPath(userExtensionsDir));
|
|
65
|
+
await new Promise<void>((resolve, reject) => {
|
|
66
|
+
fs.copyFile(currentPath, newPath, error => error ? reject(error) : resolve());
|
|
67
|
+
});
|
|
68
|
+
context.pluginEntry().updatePath(newPath);
|
|
69
|
+
context.pluginEntry().storeValue('sourceLocations', [newPath]);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.error(`[${context.pluginEntry().id}]: Failed to copy to user directory. Future sessions may not have access to this plugin.`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
55
74
|
}
|
|
56
|
-
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
protected async getPluginDir(context: PluginDeployerFileHandlerContext): Promise<string> {
|
|
78
|
+
return FileUri.fsPath(this.systemPluginsDirUri.resolve(filenamify(context.pluginEntry().id(), { replacement: '_' })));
|
|
57
79
|
}
|
|
58
80
|
}
|
|
@@ -24,6 +24,7 @@ export class PluginCliContribution implements CliContribution {
|
|
|
24
24
|
|
|
25
25
|
static PLUGINS = 'plugins';
|
|
26
26
|
static PLUGIN_MAX_SESSION_LOGS_FOLDERS = 'plugin-max-session-logs-folders';
|
|
27
|
+
static UNCOMPRESSED_PLUGINS_IN_PLACE = 'uncompressed-plugins-in-place';
|
|
27
28
|
/**
|
|
28
29
|
* This is the default value used in VSCode, see:
|
|
29
30
|
* - https://github.com/Microsoft/vscode/blob/613447d6b3f458ef7fee227e3876303bf5184580/src/vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner.ts#L32
|
|
@@ -32,6 +33,7 @@ export class PluginCliContribution implements CliContribution {
|
|
|
32
33
|
|
|
33
34
|
protected _localDir: string | undefined;
|
|
34
35
|
protected _maxSessionLogsFolders: number;
|
|
36
|
+
protected _keepUncompressedInPlace = false;
|
|
35
37
|
|
|
36
38
|
configure(conf: Argv): void {
|
|
37
39
|
conf.option(PluginCliContribution.PLUGINS, {
|
|
@@ -48,6 +50,12 @@ export class PluginCliContribution implements CliContribution {
|
|
|
48
50
|
default: PluginCliContribution.DEFAULT_PLUGIN_MAX_SESSION_LOGS_FOLDERS,
|
|
49
51
|
nargs: 1
|
|
50
52
|
});
|
|
53
|
+
|
|
54
|
+
conf.option(PluginCliContribution.UNCOMPRESSED_PLUGINS_IN_PLACE, {
|
|
55
|
+
description: 'Whether user plugins that are stored on disk as uncompressed directories should be run in place or copied to temporary folder.',
|
|
56
|
+
type: 'boolean',
|
|
57
|
+
default: false,
|
|
58
|
+
});
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
setArguments(args: Arguments): void {
|
|
@@ -60,6 +68,7 @@ export class PluginCliContribution implements CliContribution {
|
|
|
60
68
|
if (maxSessionLogsFoldersArg && Number.isInteger(maxSessionLogsFoldersArg) && maxSessionLogsFoldersArg > 0) {
|
|
61
69
|
this._maxSessionLogsFolders = maxSessionLogsFoldersArg;
|
|
62
70
|
}
|
|
71
|
+
this._keepUncompressedInPlace = Boolean(args[PluginCliContribution.UNCOMPRESSED_PLUGINS_IN_PLACE]);
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
localDir(): string | undefined {
|
|
@@ -70,4 +79,7 @@ export class PluginCliContribution implements CliContribution {
|
|
|
70
79
|
return this._maxSessionLogsFolders;
|
|
71
80
|
}
|
|
72
81
|
|
|
82
|
+
copyUncompressedPlugins(): boolean {
|
|
83
|
+
return !this._keepUncompressedInPlace;
|
|
84
|
+
}
|
|
73
85
|
}
|
|
@@ -14,12 +14,28 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
import * as fs from '@theia/core/shared/fs-extra';
|
|
17
19
|
import { PluginDeployerEntry, PluginDeployerDirectoryHandlerContext } from '../../common/plugin-protocol';
|
|
18
20
|
|
|
19
21
|
export class PluginDeployerDirectoryHandlerContextImpl implements PluginDeployerDirectoryHandlerContext {
|
|
20
22
|
|
|
21
|
-
constructor(private readonly pluginDeployerEntry: PluginDeployerEntry) {
|
|
23
|
+
constructor(private readonly pluginDeployerEntry: PluginDeployerEntry) { }
|
|
22
24
|
|
|
25
|
+
async copy(origin: string, target: string): Promise<void> {
|
|
26
|
+
const contents = await fs.readdir(origin);
|
|
27
|
+
await fs.mkdirp(target);
|
|
28
|
+
await Promise.all(contents.map(async item => {
|
|
29
|
+
const itemPath = path.resolve(origin, item);
|
|
30
|
+
const targetPath = path.resolve(target, item);
|
|
31
|
+
const stat = await fs.stat(itemPath);
|
|
32
|
+
if (stat.isDirectory()) {
|
|
33
|
+
return this.copy(itemPath, targetPath);
|
|
34
|
+
}
|
|
35
|
+
if (stat.isFile()) {
|
|
36
|
+
return new Promise<void>((resolve, reject) => fs.copyFile(itemPath, targetPath, e => e === null ? resolve() : reject(e)));
|
|
37
|
+
}
|
|
38
|
+
}));
|
|
23
39
|
}
|
|
24
40
|
|
|
25
41
|
pluginEntry(): PluginDeployerEntry {
|
|
@@ -25,7 +25,6 @@ export class PluginDeployerFileHandlerContextImpl implements PluginDeployerFileH
|
|
|
25
25
|
|
|
26
26
|
async unzip(sourcePath: string, destPath: string): Promise<void> {
|
|
27
27
|
await decompress(sourcePath, destPath);
|
|
28
|
-
return Promise.resolve();
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
pluginEntry(): PluginDeployerEntry {
|
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
18
18
|
|
|
19
19
|
import { injectable, optional, multiInject, inject, named } from '@theia/core/shared/inversify';
|
|
20
|
+
import * as semver from 'semver';
|
|
20
21
|
import {
|
|
21
22
|
PluginDeployerResolver, PluginDeployerFileHandler, PluginDeployerDirectoryHandler,
|
|
22
23
|
PluginDeployerEntry, PluginDeployer, PluginDeployerParticipant, PluginDeployerStartContext,
|
|
23
24
|
PluginDeployerResolverInit, PluginDeployerFileHandlerContext,
|
|
24
|
-
PluginDeployerDirectoryHandlerContext, PluginDeployerEntryType, PluginDeployerHandler, PluginType, UnresolvedPluginEntry
|
|
25
|
+
PluginDeployerDirectoryHandlerContext, PluginDeployerEntryType, PluginDeployerHandler, PluginType, UnresolvedPluginEntry, PluginIdentifiers, PluginDeployOptions
|
|
25
26
|
} from '../../common/plugin-protocol';
|
|
26
27
|
import { PluginDeployerEntryImpl } from './plugin-deployer-entry-impl';
|
|
27
28
|
import {
|
|
@@ -135,21 +136,26 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
135
136
|
deployPlugins.log('Deploy plugins list');
|
|
136
137
|
}
|
|
137
138
|
|
|
138
|
-
async
|
|
139
|
+
async uninstall(pluginId: PluginIdentifiers.VersionedId): Promise<void> {
|
|
140
|
+
await this.pluginDeployerHandler.uninstallPlugin(pluginId);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async undeploy(pluginId: PluginIdentifiers.VersionedId): Promise<void> {
|
|
139
144
|
if (await this.pluginDeployerHandler.undeployPlugin(pluginId)) {
|
|
140
145
|
this.onDidDeployEmitter.fire();
|
|
141
146
|
}
|
|
142
147
|
}
|
|
143
148
|
|
|
144
|
-
async deploy(plugin: UnresolvedPluginEntry): Promise<
|
|
149
|
+
async deploy(plugin: UnresolvedPluginEntry, options?: PluginDeployOptions): Promise<number> {
|
|
145
150
|
const deploy = this.measure('deploy');
|
|
146
|
-
await this.deployMultipleEntries([plugin]);
|
|
147
|
-
deploy.log(`Deploy plugin ${plugin}`);
|
|
151
|
+
const numDeployedPlugins = await this.deployMultipleEntries([plugin], options);
|
|
152
|
+
deploy.log(`Deploy plugin ${plugin.id}`);
|
|
153
|
+
return numDeployedPlugins;
|
|
148
154
|
}
|
|
149
155
|
|
|
150
|
-
protected async deployMultipleEntries(plugins: UnresolvedPluginEntry[]): Promise<
|
|
151
|
-
const pluginsToDeploy = await this.resolvePlugins(plugins);
|
|
152
|
-
|
|
156
|
+
protected async deployMultipleEntries(plugins: UnresolvedPluginEntry[], options?: PluginDeployOptions): Promise<number> {
|
|
157
|
+
const pluginsToDeploy = await this.resolvePlugins(plugins, options);
|
|
158
|
+
return this.deployPlugins(pluginsToDeploy);
|
|
153
159
|
}
|
|
154
160
|
|
|
155
161
|
/**
|
|
@@ -161,51 +167,51 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
161
167
|
* deployer.deployPlugins(await deployer.resolvePlugins(allPluginEntries));
|
|
162
168
|
* ```
|
|
163
169
|
*/
|
|
164
|
-
async resolvePlugins(plugins: UnresolvedPluginEntry[]): Promise<PluginDeployerEntry[]> {
|
|
170
|
+
async resolvePlugins(plugins: UnresolvedPluginEntry[], options?: PluginDeployOptions): Promise<PluginDeployerEntry[]> {
|
|
165
171
|
const visited = new Set<string>();
|
|
166
|
-
const
|
|
172
|
+
const hasBeenVisited = (id: string) => visited.has(id) || (visited.add(id), false);
|
|
173
|
+
const pluginsToDeploy = new Map<PluginIdentifiers.VersionedId, PluginDeployerEntry>();
|
|
174
|
+
const unversionedIdsHandled = new Map<PluginIdentifiers.UnversionedId, string[]>();
|
|
167
175
|
|
|
168
|
-
|
|
176
|
+
const queue: UnresolvedPluginEntry[] = [...plugins];
|
|
169
177
|
while (queue.length) {
|
|
170
|
-
const
|
|
178
|
+
const pendingDependencies: Array<{
|
|
171
179
|
dependencies: Map<string, string>
|
|
172
180
|
type: PluginType
|
|
173
181
|
}> = [];
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (visited.has(current.id)) {
|
|
178
|
-
continue;
|
|
179
|
-
} else {
|
|
180
|
-
workload.push(current);
|
|
181
|
-
}
|
|
182
|
-
visited.add(current.id);
|
|
183
|
-
}
|
|
184
|
-
queue = [];
|
|
185
|
-
await Promise.all(workload.map(async ({ id, type }) => {
|
|
186
|
-
if (type === undefined) {
|
|
187
|
-
type = PluginType.System;
|
|
182
|
+
await Promise.all(queue.map(async entry => {
|
|
183
|
+
if (hasBeenVisited(entry.id)) {
|
|
184
|
+
return;
|
|
188
185
|
}
|
|
186
|
+
const type = entry.type ?? PluginType.System;
|
|
189
187
|
try {
|
|
190
|
-
const pluginDeployerEntries = await this.
|
|
191
|
-
await this.applyFileHandlers(pluginDeployerEntries);
|
|
192
|
-
await this.applyDirectoryFileHandlers(pluginDeployerEntries);
|
|
188
|
+
const pluginDeployerEntries = await this.resolveAndHandle(entry.id, type, options);
|
|
193
189
|
for (const deployerEntry of pluginDeployerEntries) {
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
190
|
+
const pluginData = await this.pluginDeployerHandler.getPluginDependencies(deployerEntry);
|
|
191
|
+
const versionedId = pluginData && PluginIdentifiers.componentsToVersionedId(pluginData.metadata.model);
|
|
192
|
+
const unversionedId = versionedId && PluginIdentifiers.componentsToUnversionedId(pluginData.metadata.model);
|
|
193
|
+
if (unversionedId && !pluginsToDeploy.has(versionedId)) {
|
|
194
|
+
pluginsToDeploy.set(versionedId, deployerEntry);
|
|
195
|
+
if (pluginData.mapping) {
|
|
196
|
+
pendingDependencies.push({ dependencies: pluginData.mapping, type });
|
|
197
|
+
}
|
|
198
|
+
const otherVersions = unversionedIdsHandled.get(unversionedId) ?? [];
|
|
199
|
+
otherVersions.push(pluginData.metadata.model.version);
|
|
200
|
+
if (otherVersions.length === 1) {
|
|
201
|
+
unversionedIdsHandled.set(unversionedId, otherVersions);
|
|
202
|
+
} else {
|
|
203
|
+
this.findBestVersion(unversionedId, otherVersions, pluginsToDeploy);
|
|
199
204
|
}
|
|
200
205
|
}
|
|
201
206
|
}
|
|
202
207
|
} catch (e) {
|
|
203
|
-
console.error(`Failed to resolve plugins from '${id}'`, e);
|
|
208
|
+
console.error(`Failed to resolve plugins from '${entry.id}'`, e);
|
|
204
209
|
}
|
|
205
210
|
}));
|
|
206
|
-
|
|
211
|
+
queue.length = 0;
|
|
212
|
+
for (const { dependencies, type } of pendingDependencies) {
|
|
207
213
|
for (const [dependency, deployableDependency] of dependencies) {
|
|
208
|
-
if (!
|
|
214
|
+
if (!unversionedIdsHandled.has(dependency as PluginIdentifiers.UnversionedId)) {
|
|
209
215
|
queue.push({
|
|
210
216
|
id: deployableDependency,
|
|
211
217
|
type
|
|
@@ -217,10 +223,50 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
217
223
|
return [...pluginsToDeploy.values()];
|
|
218
224
|
}
|
|
219
225
|
|
|
226
|
+
protected async resolveAndHandle(id: string, type: PluginType, options?: PluginDeployOptions): Promise<PluginDeployerEntry[]> {
|
|
227
|
+
const entries = await this.resolvePlugin(id, type, options);
|
|
228
|
+
await this.applyFileHandlers(entries);
|
|
229
|
+
await this.applyDirectoryFileHandlers(entries);
|
|
230
|
+
return entries;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
protected findBestVersion(unversionedId: PluginIdentifiers.UnversionedId, versions: string[], knownPlugins: Map<PluginIdentifiers.VersionedId, PluginDeployerEntry>): void {
|
|
234
|
+
// If left better, return negative. Then best is index 0.
|
|
235
|
+
versions.map(version => ({ version, plugin: knownPlugins.get(PluginIdentifiers.idAndVersionToVersionedId({ version, id: unversionedId })) }))
|
|
236
|
+
.sort((left, right) => {
|
|
237
|
+
const leftPlugin = left.plugin;
|
|
238
|
+
const rightPlugin = right.plugin;
|
|
239
|
+
if (!leftPlugin && !rightPlugin) {
|
|
240
|
+
return 0;
|
|
241
|
+
}
|
|
242
|
+
if (!rightPlugin) {
|
|
243
|
+
return -1;
|
|
244
|
+
}
|
|
245
|
+
if (!leftPlugin) {
|
|
246
|
+
return 1;
|
|
247
|
+
}
|
|
248
|
+
if (leftPlugin.type === PluginType.System && rightPlugin.type === PluginType.User) {
|
|
249
|
+
return -1;
|
|
250
|
+
}
|
|
251
|
+
if (leftPlugin.type === PluginType.User && rightPlugin.type === PluginType.System) {
|
|
252
|
+
return 1;
|
|
253
|
+
}
|
|
254
|
+
if (semver.gtr(left.version, right.version)) {
|
|
255
|
+
return -1;
|
|
256
|
+
}
|
|
257
|
+
return 1;
|
|
258
|
+
}).forEach((versionedEntry, index) => {
|
|
259
|
+
if (index !== 0) {
|
|
260
|
+
// Mark as not accepted to prevent deployment of all but the winner.
|
|
261
|
+
versionedEntry.plugin?.accept();
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
220
266
|
/**
|
|
221
267
|
* deploy all plugins that have been accepted
|
|
222
268
|
*/
|
|
223
|
-
async deployPlugins(pluginsToDeploy: PluginDeployerEntry[]): Promise<
|
|
269
|
+
async deployPlugins(pluginsToDeploy: PluginDeployerEntry[]): Promise<number> {
|
|
224
270
|
const acceptedPlugins = pluginsToDeploy.filter(pluginDeployerEntry => pluginDeployerEntry.isAccepted());
|
|
225
271
|
const acceptedFrontendPlugins = pluginsToDeploy.filter(pluginDeployerEntry => pluginDeployerEntry.isAccepted(PluginDeployerEntryType.FRONTEND));
|
|
226
272
|
const acceptedBackendPlugins = pluginsToDeploy.filter(pluginDeployerEntry => pluginDeployerEntry.isAccepted(PluginDeployerEntryType.BACKEND));
|
|
@@ -237,12 +283,13 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
237
283
|
const pluginPaths = acceptedBackendPlugins.map(pluginEntry => pluginEntry.path());
|
|
238
284
|
this.logger.debug('local path to deploy on remote instance', pluginPaths);
|
|
239
285
|
|
|
240
|
-
await Promise.all([
|
|
286
|
+
const deployments = await Promise.all([
|
|
241
287
|
// start the backend plugins
|
|
242
288
|
this.pluginDeployerHandler.deployBackendPlugins(acceptedBackendPlugins),
|
|
243
289
|
this.pluginDeployerHandler.deployFrontendPlugins(acceptedFrontendPlugins)
|
|
244
290
|
]);
|
|
245
291
|
this.onDidDeployEmitter.fire(undefined);
|
|
292
|
+
return deployments.reduce<number>((accumulated, current) => accumulated += current ?? 0, 0);
|
|
246
293
|
}
|
|
247
294
|
|
|
248
295
|
/**
|
|
@@ -288,7 +335,7 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
288
335
|
/**
|
|
289
336
|
* Check a plugin ID see if there are some resolvers that can handle it. If there is a matching resolver, then we resolve the plugin
|
|
290
337
|
*/
|
|
291
|
-
public async resolvePlugin(pluginId: string, type: PluginType = PluginType.System): Promise<PluginDeployerEntry[]> {
|
|
338
|
+
public async resolvePlugin(pluginId: string, type: PluginType = PluginType.System, options?: PluginDeployOptions): Promise<PluginDeployerEntry[]> {
|
|
292
339
|
const pluginDeployerEntries: PluginDeployerEntry[] = [];
|
|
293
340
|
const foundPluginResolver = this.pluginResolvers.find(pluginResolver => pluginResolver.accept(pluginId));
|
|
294
341
|
// there is a resolver for the input
|
|
@@ -297,7 +344,7 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
297
344
|
// create context object
|
|
298
345
|
const context = new PluginDeployerResolverContextImpl(foundPluginResolver, pluginId);
|
|
299
346
|
|
|
300
|
-
await foundPluginResolver.resolve(context);
|
|
347
|
+
await foundPluginResolver.resolve(context, options);
|
|
301
348
|
|
|
302
349
|
context.getPlugins().forEach(entry => {
|
|
303
350
|
entry.type = type;
|
|
@@ -39,6 +39,7 @@ import { PluginCliContribution } from './plugin-cli-contribution';
|
|
|
39
39
|
import { PluginTheiaEnvironment } from '../common/plugin-theia-environment';
|
|
40
40
|
import { PluginTheiaDeployerParticipant } from './plugin-theia-deployer-participant';
|
|
41
41
|
import { WebviewBackendSecurityWarnings } from './webview-backend-security-warnings';
|
|
42
|
+
import { PluginUninstallationManager } from './plugin-uninstallation-manager';
|
|
42
43
|
|
|
43
44
|
export function bindMainBackend(bind: interfaces.Bind): void {
|
|
44
45
|
bind(PluginApiContribution).toSelf().inSingletonScope();
|
|
@@ -50,6 +51,8 @@ export function bindMainBackend(bind: interfaces.Bind): void {
|
|
|
50
51
|
bind(PluginDeployerContribution).toSelf().inSingletonScope();
|
|
51
52
|
bind(BackendApplicationContribution).toService(PluginDeployerContribution);
|
|
52
53
|
|
|
54
|
+
bind(PluginUninstallationManager).toSelf().inSingletonScope();
|
|
55
|
+
|
|
53
56
|
bind(PluginDeployerResolver).to(LocalDirectoryPluginDeployerResolver).inSingletonScope();
|
|
54
57
|
bind(PluginDeployerResolver).to(LocalFilePluginDeployerResolver).inSingletonScope();
|
|
55
58
|
bind(PluginDeployerResolver).to(GithubPluginDeployerResolver).inSingletonScope();
|
|
@@ -18,7 +18,7 @@ import { injectable, inject } from '@theia/core/shared/inversify';
|
|
|
18
18
|
import { CancellationToken } from '@theia/core/lib/common/cancellation';
|
|
19
19
|
import { PluginDeployerImpl } from './plugin-deployer-impl';
|
|
20
20
|
import { PluginsKeyValueStorage } from './plugins-key-value-storage';
|
|
21
|
-
import { PluginServer, PluginDeployer, PluginStorageKind, PluginType, UnresolvedPluginEntry } from '../../common/plugin-protocol';
|
|
21
|
+
import { PluginServer, PluginDeployer, PluginStorageKind, PluginType, UnresolvedPluginEntry, PluginIdentifiers, PluginDeployOptions } from '../../common/plugin-protocol';
|
|
22
22
|
import { KeysToAnyValues, KeysToKeysToAnyValue } from '../../common/types';
|
|
23
23
|
|
|
24
24
|
@injectable()
|
|
@@ -30,19 +30,27 @@ export class PluginServerHandler implements PluginServer {
|
|
|
30
30
|
@inject(PluginsKeyValueStorage)
|
|
31
31
|
protected readonly pluginsKeyValueStorage: PluginsKeyValueStorage;
|
|
32
32
|
|
|
33
|
-
deploy(pluginEntry: string, arg2?: PluginType | CancellationToken): Promise<void> {
|
|
33
|
+
async deploy(pluginEntry: string, arg2?: PluginType | CancellationToken, options?: PluginDeployOptions): Promise<void> {
|
|
34
34
|
const type = typeof arg2 === 'number' ? arg2 as PluginType : undefined;
|
|
35
|
-
|
|
35
|
+
const successfulDeployments = await this.doDeploy({
|
|
36
36
|
id: pluginEntry,
|
|
37
37
|
type: type ?? PluginType.User
|
|
38
|
-
});
|
|
38
|
+
}, options);
|
|
39
|
+
if (successfulDeployments === 0) {
|
|
40
|
+
const optionText = options ? ` and options ${JSON.stringify(options)} ` : ' ';
|
|
41
|
+
throw new Error(`Deployment of extension with ID ${pluginEntry}${optionText}failed.`);
|
|
42
|
+
}
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
protected doDeploy(pluginEntry: UnresolvedPluginEntry): Promise<
|
|
42
|
-
return this.pluginDeployer.deploy(pluginEntry);
|
|
45
|
+
protected doDeploy(pluginEntry: UnresolvedPluginEntry, options?: PluginDeployOptions): Promise<number> {
|
|
46
|
+
return this.pluginDeployer.deploy(pluginEntry, options);
|
|
43
47
|
}
|
|
44
48
|
|
|
45
|
-
|
|
49
|
+
uninstall(pluginId: PluginIdentifiers.VersionedId): Promise<void> {
|
|
50
|
+
return this.pluginDeployer.uninstall(pluginId);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
undeploy(pluginId: PluginIdentifiers.VersionedId): Promise<void> {
|
|
46
54
|
return this.pluginDeployer.undeploy(pluginId);
|
|
47
55
|
}
|
|
48
56
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2022 Ericsson and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { Emitter, Event } from '@theia/core';
|
|
18
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
19
|
+
import { PluginIdentifiers } from '../../common';
|
|
20
|
+
|
|
21
|
+
@injectable()
|
|
22
|
+
export class PluginUninstallationManager {
|
|
23
|
+
protected readonly onDidChangeUninstalledPluginsEmitter = new Emitter<readonly PluginIdentifiers.VersionedId[]>();
|
|
24
|
+
|
|
25
|
+
get onDidChangeUninstalledPlugins(): Event<readonly PluginIdentifiers.VersionedId[]> {
|
|
26
|
+
return this.onDidChangeUninstalledPluginsEmitter.event;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
protected uninstalledPlugins: PluginIdentifiers.VersionedId[] = [];
|
|
30
|
+
|
|
31
|
+
protected fireDidChange(): void {
|
|
32
|
+
this.onDidChangeUninstalledPluginsEmitter.fire(Object.freeze(this.uninstalledPlugins.slice()));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
markAsUninstalled(...pluginIds: PluginIdentifiers.VersionedId[]): boolean {
|
|
36
|
+
let didChange = false;
|
|
37
|
+
for (const id of pluginIds) { didChange = this.markOneAsUninstalled(id) || didChange; }
|
|
38
|
+
if (didChange) { this.fireDidChange(); }
|
|
39
|
+
return didChange;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
protected markOneAsUninstalled(pluginId: PluginIdentifiers.VersionedId): boolean {
|
|
43
|
+
if (!this.uninstalledPlugins.includes(pluginId)) {
|
|
44
|
+
this.uninstalledPlugins.push(pluginId);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
markAsInstalled(...pluginIds: PluginIdentifiers.VersionedId[]): boolean {
|
|
51
|
+
let didChange = false;
|
|
52
|
+
for (const id of pluginIds) { didChange = this.markOneAsInstalled(id) || didChange; }
|
|
53
|
+
if (didChange) { this.fireDidChange(); }
|
|
54
|
+
return didChange;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected markOneAsInstalled(pluginId: PluginIdentifiers.VersionedId): boolean {
|
|
58
|
+
let index: number;
|
|
59
|
+
let didChange = false;
|
|
60
|
+
while ((index = this.uninstalledPlugins.indexOf(pluginId)) !== -1) {
|
|
61
|
+
this.uninstalledPlugins.splice(index, 1);
|
|
62
|
+
didChange = true;
|
|
63
|
+
}
|
|
64
|
+
return didChange;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
isUninstalled(pluginId: PluginIdentifiers.VersionedId): boolean {
|
|
68
|
+
return this.uninstalledPlugins.includes(pluginId);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
getUninstalledPluginIds(): readonly PluginIdentifiers.VersionedId[] {
|
|
72
|
+
return Object.freeze(this.uninstalledPlugins.slice());
|
|
73
|
+
}
|
|
74
|
+
}
|