@theia/plugin-ext-vscode 1.53.0-next.5 → 1.53.0-next.55
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/README.md +32 -32
- package/lib/browser/plugin-vscode-commands-contribution.d.ts +2 -0
- package/lib/browser/plugin-vscode-commands-contribution.d.ts.map +1 -1
- package/lib/browser/plugin-vscode-commands-contribution.js +24 -1
- package/lib/browser/plugin-vscode-commands-contribution.js.map +1 -1
- package/lib/common/plugin-vscode-types.d.ts +1 -1
- package/package.json +16 -16
- package/src/browser/plugin-vscode-commands-contribution.ts +987 -951
- package/src/browser/plugin-vscode-contribution.ts +47 -47
- package/src/browser/plugin-vscode-frontend-module.ts +30 -30
- package/src/common/plugin-vscode-environment.ts +59 -59
- package/src/common/plugin-vscode-types.ts +20 -20
- package/src/common/plugin-vscode-uri.ts +45 -45
- package/src/node/context/plugin-vscode-init-fe.ts +43 -43
- package/src/node/local-vsix-file-plugin-deployer-resolver.ts +51 -51
- package/src/node/package.spec.ts +28 -28
- package/src/node/plugin-vscode-backend-module.ts +46 -46
- package/src/node/plugin-vscode-cli-contribution.ts +64 -64
- package/src/node/plugin-vscode-deployer-participant.ts +48 -48
- package/src/node/plugin-vscode-directory-handler.ts +123 -123
- package/src/node/plugin-vscode-file-handler.ts +62 -62
- package/src/node/plugin-vscode-init.ts +80 -80
- package/src/node/plugin-vscode-utils.ts +101 -101
- package/src/node/scanner-vscode.ts +113 -113
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
// *****************************************************************************
|
|
2
|
-
// Copyright (C) 2018 Red Hat, Inc. 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-only WITH Classpath-exception-2.0
|
|
15
|
-
// *****************************************************************************
|
|
16
|
-
|
|
17
|
-
import { PluginDeployerFileHandler, PluginDeployerEntry, PluginDeployerFileHandlerContext } from '@theia/plugin-ext';
|
|
18
|
-
import * as filenamify from 'filenamify';
|
|
19
|
-
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
20
|
-
import * as fs from '@theia/core/shared/fs-extra';
|
|
21
|
-
import { PluginVSCodeEnvironment } from '../common/plugin-vscode-environment';
|
|
22
|
-
import { FileUri } from '@theia/core/lib/common/file-uri';
|
|
23
|
-
import { unpackToDeploymentDir } from './plugin-vscode-utils';
|
|
24
|
-
|
|
25
|
-
export const isVSCodePluginFile = (pluginPath?: string) => Boolean(pluginPath && (pluginPath.endsWith('.vsix') || pluginPath.endsWith('.tgz')));
|
|
26
|
-
|
|
27
|
-
@injectable()
|
|
28
|
-
export class PluginVsCodeFileHandler implements PluginDeployerFileHandler {
|
|
29
|
-
@inject(PluginVSCodeEnvironment)
|
|
30
|
-
protected readonly environment: PluginVSCodeEnvironment;
|
|
31
|
-
|
|
32
|
-
async accept(resolvedPlugin: PluginDeployerEntry): Promise<boolean> {
|
|
33
|
-
return resolvedPlugin.isFile().then(file => {
|
|
34
|
-
if (!file) {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
return isVSCodePluginFile(resolvedPlugin.path());
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async handle(context: PluginDeployerFileHandlerContext): Promise<void> {
|
|
42
|
-
const id = this.getNormalizedExtensionId(context.pluginEntry().id());
|
|
43
|
-
const extensionDeploymentDir = await unpackToDeploymentDir(this.environment, context.pluginEntry().path(), id);
|
|
44
|
-
context.pluginEntry().updatePath(extensionDeploymentDir);
|
|
45
|
-
console.log(`root path: ${context.pluginEntry().rootPath}`);
|
|
46
|
-
const originalPath = context.pluginEntry().originalPath();
|
|
47
|
-
if (originalPath && originalPath !== extensionDeploymentDir) {
|
|
48
|
-
const tempDirUri = await this.environment.getTempDirUri();
|
|
49
|
-
if (originalPath.startsWith(FileUri.fsPath(tempDirUri))) {
|
|
50
|
-
try {
|
|
51
|
-
await fs.remove(FileUri.fsPath(originalPath));
|
|
52
|
-
} catch (e) {
|
|
53
|
-
console.error(`[${id}]: failed to remove temporary files: "${originalPath}"`, e);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
protected getNormalizedExtensionId(pluginId: string): string {
|
|
60
|
-
return filenamify(pluginId, { replacement: '_' }).replace(/\.vsix$/, '');
|
|
61
|
-
}
|
|
62
|
-
}
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2018 Red Hat, Inc. 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-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { PluginDeployerFileHandler, PluginDeployerEntry, PluginDeployerFileHandlerContext } from '@theia/plugin-ext';
|
|
18
|
+
import * as filenamify from 'filenamify';
|
|
19
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
20
|
+
import * as fs from '@theia/core/shared/fs-extra';
|
|
21
|
+
import { PluginVSCodeEnvironment } from '../common/plugin-vscode-environment';
|
|
22
|
+
import { FileUri } from '@theia/core/lib/common/file-uri';
|
|
23
|
+
import { unpackToDeploymentDir } from './plugin-vscode-utils';
|
|
24
|
+
|
|
25
|
+
export const isVSCodePluginFile = (pluginPath?: string) => Boolean(pluginPath && (pluginPath.endsWith('.vsix') || pluginPath.endsWith('.tgz')));
|
|
26
|
+
|
|
27
|
+
@injectable()
|
|
28
|
+
export class PluginVsCodeFileHandler implements PluginDeployerFileHandler {
|
|
29
|
+
@inject(PluginVSCodeEnvironment)
|
|
30
|
+
protected readonly environment: PluginVSCodeEnvironment;
|
|
31
|
+
|
|
32
|
+
async accept(resolvedPlugin: PluginDeployerEntry): Promise<boolean> {
|
|
33
|
+
return resolvedPlugin.isFile().then(file => {
|
|
34
|
+
if (!file) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return isVSCodePluginFile(resolvedPlugin.path());
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async handle(context: PluginDeployerFileHandlerContext): Promise<void> {
|
|
42
|
+
const id = this.getNormalizedExtensionId(context.pluginEntry().id());
|
|
43
|
+
const extensionDeploymentDir = await unpackToDeploymentDir(this.environment, context.pluginEntry().path(), id);
|
|
44
|
+
context.pluginEntry().updatePath(extensionDeploymentDir);
|
|
45
|
+
console.log(`root path: ${context.pluginEntry().rootPath}`);
|
|
46
|
+
const originalPath = context.pluginEntry().originalPath();
|
|
47
|
+
if (originalPath && originalPath !== extensionDeploymentDir) {
|
|
48
|
+
const tempDirUri = await this.environment.getTempDirUri();
|
|
49
|
+
if (originalPath.startsWith(FileUri.fsPath(tempDirUri))) {
|
|
50
|
+
try {
|
|
51
|
+
await fs.remove(FileUri.fsPath(originalPath));
|
|
52
|
+
} catch (e) {
|
|
53
|
+
console.error(`[${id}]: failed to remove temporary files: "${originalPath}"`, e);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
protected getNormalizedExtensionId(pluginId: string): string {
|
|
60
|
+
return filenamify(pluginId, { replacement: '_' }).replace(/\.vsix$/, '');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
// *****************************************************************************
|
|
2
|
-
// Copyright (C) 2018-2019 Red Hat, Inc.
|
|
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-only WITH Classpath-exception-2.0
|
|
15
|
-
// *****************************************************************************
|
|
16
|
-
|
|
17
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
18
|
-
|
|
19
|
-
import * as theia from '@theia/plugin';
|
|
20
|
-
import { BackendInitializationFn, PluginAPIFactory, Plugin, emptyPlugin } from '@theia/plugin-ext';
|
|
21
|
-
import { VSCODE_DEFAULT_API_VERSION } from '../common/plugin-vscode-types';
|
|
22
|
-
|
|
23
|
-
process.env['VSCODE_PID'] = process.env['THEIA_PARENT_PID'];
|
|
24
|
-
|
|
25
|
-
const pluginsApiImpl = new Map<string, typeof theia>();
|
|
26
|
-
const plugins = new Array<Plugin>();
|
|
27
|
-
let defaultApi: typeof theia;
|
|
28
|
-
let isLoadOverride = false;
|
|
29
|
-
let pluginApiFactory: PluginAPIFactory;
|
|
30
|
-
|
|
31
|
-
export const doInitialization: BackendInitializationFn = (apiFactory: PluginAPIFactory, plugin: Plugin) => {
|
|
32
|
-
pluginsApiImpl.set(plugin.model.id, createVSCodeAPI(apiFactory, plugin));
|
|
33
|
-
plugins.push(plugin);
|
|
34
|
-
pluginApiFactory = apiFactory;
|
|
35
|
-
|
|
36
|
-
if (!isLoadOverride) {
|
|
37
|
-
overrideInternalLoad();
|
|
38
|
-
isLoadOverride = true;
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
function createVSCodeAPI(apiFactory: PluginAPIFactory, plugin: Plugin): typeof theia {
|
|
43
|
-
const vscode = apiFactory(plugin);
|
|
44
|
-
|
|
45
|
-
// override the version for vscode to be a VSCode version
|
|
46
|
-
(<any>vscode).version = process.env['VSCODE_API_VERSION'] || VSCODE_DEFAULT_API_VERSION;
|
|
47
|
-
return vscode;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function overrideInternalLoad(): void {
|
|
51
|
-
const module = require('module');
|
|
52
|
-
const vscodeModuleName = 'vscode';
|
|
53
|
-
// save original load method
|
|
54
|
-
const internalLoad = module._load;
|
|
55
|
-
|
|
56
|
-
// if we try to resolve theia module, return the filename entry to use cache.
|
|
57
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
|
-
module._load = function (request: string, parent: any, isMain: {}): any {
|
|
59
|
-
if (request !== vscodeModuleName) {
|
|
60
|
-
return internalLoad.apply(this, arguments);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const plugin = findPlugin(parent.filename);
|
|
64
|
-
if (plugin) {
|
|
65
|
-
const apiImpl = pluginsApiImpl.get(plugin.model.id);
|
|
66
|
-
return apiImpl;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (!defaultApi) {
|
|
70
|
-
console.warn(`Could not identify plugin for 'Theia' require call from ${parent.filename}`);
|
|
71
|
-
defaultApi = createVSCodeAPI(pluginApiFactory, emptyPlugin);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return defaultApi;
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function findPlugin(filePath: string): Plugin | undefined {
|
|
79
|
-
return plugins.find(plugin => filePath.startsWith(plugin.pluginFolder));
|
|
80
|
-
}
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2018-2019 Red Hat, Inc.
|
|
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-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
18
|
+
|
|
19
|
+
import * as theia from '@theia/plugin';
|
|
20
|
+
import { BackendInitializationFn, PluginAPIFactory, Plugin, emptyPlugin } from '@theia/plugin-ext';
|
|
21
|
+
import { VSCODE_DEFAULT_API_VERSION } from '../common/plugin-vscode-types';
|
|
22
|
+
|
|
23
|
+
process.env['VSCODE_PID'] = process.env['THEIA_PARENT_PID'];
|
|
24
|
+
|
|
25
|
+
const pluginsApiImpl = new Map<string, typeof theia>();
|
|
26
|
+
const plugins = new Array<Plugin>();
|
|
27
|
+
let defaultApi: typeof theia;
|
|
28
|
+
let isLoadOverride = false;
|
|
29
|
+
let pluginApiFactory: PluginAPIFactory;
|
|
30
|
+
|
|
31
|
+
export const doInitialization: BackendInitializationFn = (apiFactory: PluginAPIFactory, plugin: Plugin) => {
|
|
32
|
+
pluginsApiImpl.set(plugin.model.id, createVSCodeAPI(apiFactory, plugin));
|
|
33
|
+
plugins.push(plugin);
|
|
34
|
+
pluginApiFactory = apiFactory;
|
|
35
|
+
|
|
36
|
+
if (!isLoadOverride) {
|
|
37
|
+
overrideInternalLoad();
|
|
38
|
+
isLoadOverride = true;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function createVSCodeAPI(apiFactory: PluginAPIFactory, plugin: Plugin): typeof theia {
|
|
43
|
+
const vscode = apiFactory(plugin);
|
|
44
|
+
|
|
45
|
+
// override the version for vscode to be a VSCode version
|
|
46
|
+
(<any>vscode).version = process.env['VSCODE_API_VERSION'] || VSCODE_DEFAULT_API_VERSION;
|
|
47
|
+
return vscode;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function overrideInternalLoad(): void {
|
|
51
|
+
const module = require('module');
|
|
52
|
+
const vscodeModuleName = 'vscode';
|
|
53
|
+
// save original load method
|
|
54
|
+
const internalLoad = module._load;
|
|
55
|
+
|
|
56
|
+
// if we try to resolve theia module, return the filename entry to use cache.
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
|
+
module._load = function (request: string, parent: any, isMain: {}): any {
|
|
59
|
+
if (request !== vscodeModuleName) {
|
|
60
|
+
return internalLoad.apply(this, arguments);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const plugin = findPlugin(parent.filename);
|
|
64
|
+
if (plugin) {
|
|
65
|
+
const apiImpl = pluginsApiImpl.get(plugin.model.id);
|
|
66
|
+
return apiImpl;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!defaultApi) {
|
|
70
|
+
console.warn(`Could not identify plugin for 'Theia' require call from ${parent.filename}`);
|
|
71
|
+
defaultApi = createVSCodeAPI(pluginApiFactory, emptyPlugin);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return defaultApi;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function findPlugin(filePath: string): Plugin | undefined {
|
|
79
|
+
return plugins.find(plugin => filePath.startsWith(plugin.pluginFolder));
|
|
80
|
+
}
|
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
// *****************************************************************************
|
|
2
|
-
// Copyright (C) 2023 STMicroelectronics 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-only WITH Classpath-exception-2.0
|
|
15
|
-
// *****************************************************************************
|
|
16
|
-
|
|
17
|
-
import * as decompress from 'decompress';
|
|
18
|
-
import * as path from 'path';
|
|
19
|
-
import * as filenamify from 'filenamify';
|
|
20
|
-
import { FileUri } from '@theia/core/lib/node';
|
|
21
|
-
import * as fs from '@theia/core/shared/fs-extra';
|
|
22
|
-
import { PluginVSCodeEnvironment } from '../common/plugin-vscode-environment';
|
|
23
|
-
|
|
24
|
-
export async function decompressExtension(sourcePath: string, destPath: string): Promise<boolean> {
|
|
25
|
-
try {
|
|
26
|
-
await decompress(sourcePath, destPath);
|
|
27
|
-
if (sourcePath.endsWith('.tgz')) {
|
|
28
|
-
// unzip node_modules from built-in extensions, see https://github.com/eclipse-theia/theia/issues/5756
|
|
29
|
-
const extensionPath = path.join(destPath, 'package');
|
|
30
|
-
const vscodeNodeModulesPath = path.join(extensionPath, 'vscode_node_modules.zip');
|
|
31
|
-
if (await fs.pathExists(vscodeNodeModulesPath)) {
|
|
32
|
-
await decompress(vscodeNodeModulesPath, path.join(extensionPath, 'node_modules'));
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return true;
|
|
36
|
-
} catch (error) {
|
|
37
|
-
console.error(`Failed to decompress ${sourcePath} to ${destPath}: ${error}`);
|
|
38
|
-
throw error;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function existsInDeploymentDir(env: PluginVSCodeEnvironment, extensionId: string): Promise<boolean> {
|
|
43
|
-
return fs.pathExists(await getExtensionDeploymentDir(env, extensionId));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export const TMP_DIR_PREFIX = 'tmp-vscode-unpacked-';
|
|
47
|
-
export async function unpackToDeploymentDir(env: PluginVSCodeEnvironment, sourcePath: string, extensionId: string): Promise<string> {
|
|
48
|
-
const extensionDeploymentDir = await getExtensionDeploymentDir(env, extensionId);
|
|
49
|
-
if (await fs.pathExists(extensionDeploymentDir)) {
|
|
50
|
-
console.log(`[${extensionId}]: deployment dir "${extensionDeploymentDir}" already exists`);
|
|
51
|
-
return extensionDeploymentDir;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const tempDir = await getTempDir(env, TMP_DIR_PREFIX);
|
|
55
|
-
try {
|
|
56
|
-
console.log(`[${extensionId}]: trying to decompress "${sourcePath}" into "${tempDir}"...`);
|
|
57
|
-
if (!await decompressExtension(sourcePath, tempDir)) {
|
|
58
|
-
await fs.remove(tempDir);
|
|
59
|
-
const msg = `[${extensionId}]: decompressing "${sourcePath}" to "${tempDir}" failed`;
|
|
60
|
-
console.error(msg);
|
|
61
|
-
throw new Error(msg);
|
|
62
|
-
}
|
|
63
|
-
} catch (e) {
|
|
64
|
-
await fs.remove(tempDir);
|
|
65
|
-
const msg = `[${extensionId}]: error while decompressing "${sourcePath}" to "${tempDir}"`;
|
|
66
|
-
console.error(msg, e);
|
|
67
|
-
throw e;
|
|
68
|
-
}
|
|
69
|
-
console.log(`[${extensionId}]: decompressed to temp dir "${tempDir}"`);
|
|
70
|
-
|
|
71
|
-
try {
|
|
72
|
-
console.log(`[${extensionId}]: renaming to extension dir "${extensionDeploymentDir}"...`);
|
|
73
|
-
await fs.rename(tempDir, extensionDeploymentDir);
|
|
74
|
-
return extensionDeploymentDir;
|
|
75
|
-
} catch (e) {
|
|
76
|
-
await fs.remove(tempDir);
|
|
77
|
-
console.error(`[${extensionId}]: error while renaming "${tempDir}" to "${extensionDeploymentDir}"`, e);
|
|
78
|
-
throw e;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export async function getExtensionDeploymentDir(env: PluginVSCodeEnvironment, extensionId: string): Promise<string> {
|
|
83
|
-
const deployedPluginsDirUri = await env.getDeploymentDirUri();
|
|
84
|
-
const normalizedExtensionId = filenamify(extensionId, { replacement: '_' });
|
|
85
|
-
const extensionDeploymentDirPath = FileUri.fsPath(deployedPluginsDirUri.resolve(normalizedExtensionId));
|
|
86
|
-
return extensionDeploymentDirPath;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export async function getTempDir(env: PluginVSCodeEnvironment, prefix: string): Promise<string> {
|
|
90
|
-
const deploymentDirPath = FileUri.fsPath(await env.getDeploymentDirUri());
|
|
91
|
-
try {
|
|
92
|
-
if (!await fs.pathExists(deploymentDirPath)) {
|
|
93
|
-
console.log(`Creating deployment dir ${deploymentDirPath}`);
|
|
94
|
-
await fs.mkdirs(deploymentDirPath);
|
|
95
|
-
}
|
|
96
|
-
return await fs.mkdtemp(path.join(deploymentDirPath, prefix));
|
|
97
|
-
} catch (error) {
|
|
98
|
-
console.error(`Failed to create deployment dir ${deploymentDirPath}: ${error}`);
|
|
99
|
-
throw error;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2023 STMicroelectronics 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-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import * as decompress from 'decompress';
|
|
18
|
+
import * as path from 'path';
|
|
19
|
+
import * as filenamify from 'filenamify';
|
|
20
|
+
import { FileUri } from '@theia/core/lib/node';
|
|
21
|
+
import * as fs from '@theia/core/shared/fs-extra';
|
|
22
|
+
import { PluginVSCodeEnvironment } from '../common/plugin-vscode-environment';
|
|
23
|
+
|
|
24
|
+
export async function decompressExtension(sourcePath: string, destPath: string): Promise<boolean> {
|
|
25
|
+
try {
|
|
26
|
+
await decompress(sourcePath, destPath);
|
|
27
|
+
if (sourcePath.endsWith('.tgz')) {
|
|
28
|
+
// unzip node_modules from built-in extensions, see https://github.com/eclipse-theia/theia/issues/5756
|
|
29
|
+
const extensionPath = path.join(destPath, 'package');
|
|
30
|
+
const vscodeNodeModulesPath = path.join(extensionPath, 'vscode_node_modules.zip');
|
|
31
|
+
if (await fs.pathExists(vscodeNodeModulesPath)) {
|
|
32
|
+
await decompress(vscodeNodeModulesPath, path.join(extensionPath, 'node_modules'));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error(`Failed to decompress ${sourcePath} to ${destPath}: ${error}`);
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function existsInDeploymentDir(env: PluginVSCodeEnvironment, extensionId: string): Promise<boolean> {
|
|
43
|
+
return fs.pathExists(await getExtensionDeploymentDir(env, extensionId));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const TMP_DIR_PREFIX = 'tmp-vscode-unpacked-';
|
|
47
|
+
export async function unpackToDeploymentDir(env: PluginVSCodeEnvironment, sourcePath: string, extensionId: string): Promise<string> {
|
|
48
|
+
const extensionDeploymentDir = await getExtensionDeploymentDir(env, extensionId);
|
|
49
|
+
if (await fs.pathExists(extensionDeploymentDir)) {
|
|
50
|
+
console.log(`[${extensionId}]: deployment dir "${extensionDeploymentDir}" already exists`);
|
|
51
|
+
return extensionDeploymentDir;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const tempDir = await getTempDir(env, TMP_DIR_PREFIX);
|
|
55
|
+
try {
|
|
56
|
+
console.log(`[${extensionId}]: trying to decompress "${sourcePath}" into "${tempDir}"...`);
|
|
57
|
+
if (!await decompressExtension(sourcePath, tempDir)) {
|
|
58
|
+
await fs.remove(tempDir);
|
|
59
|
+
const msg = `[${extensionId}]: decompressing "${sourcePath}" to "${tempDir}" failed`;
|
|
60
|
+
console.error(msg);
|
|
61
|
+
throw new Error(msg);
|
|
62
|
+
}
|
|
63
|
+
} catch (e) {
|
|
64
|
+
await fs.remove(tempDir);
|
|
65
|
+
const msg = `[${extensionId}]: error while decompressing "${sourcePath}" to "${tempDir}"`;
|
|
66
|
+
console.error(msg, e);
|
|
67
|
+
throw e;
|
|
68
|
+
}
|
|
69
|
+
console.log(`[${extensionId}]: decompressed to temp dir "${tempDir}"`);
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
console.log(`[${extensionId}]: renaming to extension dir "${extensionDeploymentDir}"...`);
|
|
73
|
+
await fs.rename(tempDir, extensionDeploymentDir);
|
|
74
|
+
return extensionDeploymentDir;
|
|
75
|
+
} catch (e) {
|
|
76
|
+
await fs.remove(tempDir);
|
|
77
|
+
console.error(`[${extensionId}]: error while renaming "${tempDir}" to "${extensionDeploymentDir}"`, e);
|
|
78
|
+
throw e;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export async function getExtensionDeploymentDir(env: PluginVSCodeEnvironment, extensionId: string): Promise<string> {
|
|
83
|
+
const deployedPluginsDirUri = await env.getDeploymentDirUri();
|
|
84
|
+
const normalizedExtensionId = filenamify(extensionId, { replacement: '_' });
|
|
85
|
+
const extensionDeploymentDirPath = FileUri.fsPath(deployedPluginsDirUri.resolve(normalizedExtensionId));
|
|
86
|
+
return extensionDeploymentDirPath;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function getTempDir(env: PluginVSCodeEnvironment, prefix: string): Promise<string> {
|
|
90
|
+
const deploymentDirPath = FileUri.fsPath(await env.getDeploymentDirUri());
|
|
91
|
+
try {
|
|
92
|
+
if (!await fs.pathExists(deploymentDirPath)) {
|
|
93
|
+
console.log(`Creating deployment dir ${deploymentDirPath}`);
|
|
94
|
+
await fs.mkdirs(deploymentDirPath);
|
|
95
|
+
}
|
|
96
|
+
return await fs.mkdtemp(path.join(deploymentDirPath, prefix));
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error(`Failed to create deployment dir ${deploymentDirPath}: ${error}`);
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|