deploy: current vibn theia state
Made-with: Cursor
This commit is contained in:
10
packages/plugin-ext-vscode/.eslintrc.js
Normal file
10
packages/plugin-ext-vscode/.eslintrc.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
extends: [
|
||||
'../../configs/build.eslintrc.json'
|
||||
],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: 'tsconfig.json'
|
||||
}
|
||||
};
|
||||
32
packages/plugin-ext-vscode/README.md
Normal file
32
packages/plugin-ext-vscode/README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
<div align='center'>
|
||||
|
||||
<br />
|
||||
|
||||
<img src='https://raw.githubusercontent.com/eclipse-theia/theia/master/logo/theia.svg?sanitize=true' alt='theia-ext-logo' width='100px' />
|
||||
|
||||
<h2>ECLIPSE THEIA - PLUGIN-EXT-VSCODE EXTENSION</h2>
|
||||
|
||||
<hr />
|
||||
|
||||
</div>
|
||||
|
||||
## Description
|
||||
|
||||
The `@theia/plugin-ext-vscode` extension contributes functionality to be able to successfully run VS Code extensions in the application.
|
||||
The extension is mandatory for any application which requires VS Code extension support.
|
||||
|
||||
## Additional Information
|
||||
|
||||
- [API documentation for `@theia/plugin-ext-vscode`](https://eclipse-theia.github.io/theia/docs/next/modules/_theia_plugin-ext-vscode.html)
|
||||
- [Theia - GitHub](https://github.com/eclipse-theia/theia)
|
||||
- [Theia - Website](https://theia-ide.org/)
|
||||
|
||||
## License
|
||||
|
||||
- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
|
||||
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)
|
||||
|
||||
## Trademark
|
||||
|
||||
"Theia" is a trademark of the Eclipse Foundation
|
||||
<https://www.eclipse.org/theia>
|
||||
65
packages/plugin-ext-vscode/package.json
Normal file
65
packages/plugin-ext-vscode/package.json
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "@theia/plugin-ext-vscode",
|
||||
"version": "1.68.0",
|
||||
"description": "Theia - Plugin Extension for VsCode",
|
||||
"dependencies": {
|
||||
"@theia/callhierarchy": "1.68.0",
|
||||
"@theia/core": "1.68.0",
|
||||
"@theia/editor": "1.68.0",
|
||||
"@theia/filesystem": "1.68.0",
|
||||
"@theia/monaco": "1.68.0",
|
||||
"@theia/monaco-editor-core": "1.96.302",
|
||||
"@theia/navigator": "1.68.0",
|
||||
"@theia/outline-view": "1.68.0",
|
||||
"@theia/plugin": "1.68.0",
|
||||
"@theia/plugin-ext": "1.68.0",
|
||||
"@theia/scm": "1.68.0",
|
||||
"@theia/terminal": "1.68.0",
|
||||
"@theia/typehierarchy": "1.68.0",
|
||||
"@theia/userstorage": "1.68.0",
|
||||
"@theia/workspace": "1.68.0",
|
||||
"decompress": "^4.2.1",
|
||||
"filenamify": "^4.1.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"theiaExtensions": [
|
||||
{
|
||||
"backend": "lib/node/plugin-vscode-backend-module",
|
||||
"frontend": "lib/browser/plugin-vscode-frontend-module"
|
||||
}
|
||||
],
|
||||
"keywords": [
|
||||
"theia-extension"
|
||||
],
|
||||
"license": "EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eclipse-theia/theia.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/eclipse-theia/theia/issues"
|
||||
},
|
||||
"homepage": "https://github.com/eclipse-theia/theia",
|
||||
"files": [
|
||||
"lib",
|
||||
"src"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "theiaext build",
|
||||
"clean": "theiaext clean",
|
||||
"compile": "theiaext compile",
|
||||
"lint": "theiaext lint",
|
||||
"test": "theiaext test",
|
||||
"watch": "theiaext watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/ext-scripts": "1.68.0"
|
||||
},
|
||||
"nyc": {
|
||||
"extends": "../../configs/nyc.json"
|
||||
},
|
||||
"gitHead": "21358137e41342742707f660b8e222f940a27652"
|
||||
}
|
||||
1101
packages/plugin-ext-vscode/src/browser/plugin-vscode-commands-contribution.ts
Executable file
1101
packages/plugin-ext-vscode/src/browser/plugin-vscode-commands-contribution.ts
Executable file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2020 TypeFox and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { UserStorageUri } from '@theia/userstorage/lib/browser/user-storage-uri';
|
||||
import { FileServiceContribution, FileService } from '@theia/filesystem/lib/browser/file-service';
|
||||
import { Schemes } from '@theia/plugin-ext/lib/common/uri-components';
|
||||
import { DelegatingFileSystemProvider } from '@theia/filesystem/lib/common/delegating-file-system-provider';
|
||||
|
||||
@injectable()
|
||||
export class PluginVSCodeContribution implements FileServiceContribution {
|
||||
|
||||
registerFileSystemProviders(service: FileService): void {
|
||||
this.mapSchemas(service, Schemes.vscodeRemote, 'file');
|
||||
this.mapSchemas(service, Schemes.userData, UserStorageUri.scheme);
|
||||
}
|
||||
|
||||
protected mapSchemas(service: FileService, from: string, to: string): void {
|
||||
service.onWillActivateFileSystemProvider(event => {
|
||||
if (event.scheme === from) {
|
||||
event.waitUntil((async () => {
|
||||
const provider = await service.activateProvider(to);
|
||||
service.registerProvider(from, new DelegatingFileSystemProvider(provider, {
|
||||
uriConverter: {
|
||||
to: resource => resource.withScheme(to),
|
||||
from: resource => resource.withScheme(from)
|
||||
}
|
||||
}));
|
||||
})());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2018 Red Hat, Inc. and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { ContainerModule } from '@theia/core/shared/inversify';
|
||||
import { CommandContribution } from '@theia/core';
|
||||
import { PluginVscodeCommandsContribution } from './plugin-vscode-commands-contribution';
|
||||
import { PluginVSCodeEnvironment } from '../common/plugin-vscode-environment';
|
||||
import { PluginVSCodeContribution } from './plugin-vscode-contribution';
|
||||
import { FileServiceContribution } from '@theia/filesystem/lib/browser/file-service';
|
||||
|
||||
export default new ContainerModule(bind => {
|
||||
bind(PluginVSCodeEnvironment).toSelf().inSingletonScope();
|
||||
bind(PluginVscodeCommandsContribution).toSelf().inSingletonScope();
|
||||
bind(CommandContribution).toService(PluginVscodeCommandsContribution);
|
||||
bind(PluginVSCodeContribution).toSelf().inSingletonScope();
|
||||
bind(FileServiceContribution).toService(PluginVSCodeContribution);
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2020 TypeFox and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
||||
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
|
||||
@injectable()
|
||||
export class PluginVSCodeEnvironment {
|
||||
|
||||
@inject(EnvVariablesServer)
|
||||
protected readonly environments: EnvVariablesServer;
|
||||
|
||||
protected _userExtensionsDirUri: URI | undefined;
|
||||
protected _deployedPluginsUri: URI | undefined;
|
||||
protected _tmpDirUri: URI | undefined;
|
||||
|
||||
async getUserExtensionsDirUri(): Promise<URI> {
|
||||
if (!this._userExtensionsDirUri) {
|
||||
const configDir = new URI(await this.environments.getConfigDirUri());
|
||||
this._userExtensionsDirUri = configDir.resolve('extensions');
|
||||
}
|
||||
return this._userExtensionsDirUri;
|
||||
}
|
||||
|
||||
async getDeploymentDirUri(): Promise<URI> {
|
||||
if (!this._deployedPluginsUri) {
|
||||
const configDir = new URI(await this.environments.getConfigDirUri());
|
||||
this._deployedPluginsUri = configDir.resolve('deployedPlugins');
|
||||
}
|
||||
return this._deployedPluginsUri;
|
||||
}
|
||||
|
||||
async getTempDirUri(prefix?: string): Promise<URI> {
|
||||
if (!this._tmpDirUri) {
|
||||
const configDir: URI = new URI(await this.environments.getConfigDirUri());
|
||||
this._tmpDirUri = configDir.resolve('tmp');
|
||||
}
|
||||
|
||||
if (prefix) {
|
||||
return this._tmpDirUri.resolve(prefix);
|
||||
}
|
||||
|
||||
return this._tmpDirUri;
|
||||
}
|
||||
}
|
||||
20
packages/plugin-ext-vscode/src/common/plugin-vscode-types.ts
Normal file
20
packages/plugin-ext-vscode/src/common/plugin-vscode-types.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2020 Ericsson and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { DEFAULT_SUPPORTED_API_VERSION } from '@theia/core/shared/@theia/application-package/lib/api';
|
||||
|
||||
export const VSCODE_DEFAULT_API_VERSION = DEFAULT_SUPPORTED_API_VERSION;
|
||||
export const VSX_REGISTRY_URL_DEFAULT = 'https://open-vsx.org';
|
||||
45
packages/plugin-ext-vscode/src/common/plugin-vscode-uri.ts
Normal file
45
packages/plugin-ext-vscode/src/common/plugin-vscode-uri.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2022 Ericsson and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
|
||||
/**
|
||||
* Static methods for identifying a plugin as the target of the VSCode deployment system.
|
||||
* In practice, this means that it will be resolved and deployed by the Open-VSX system.
|
||||
*/
|
||||
export namespace VSCodeExtensionUri {
|
||||
export const SCHEME = 'vscode-extension';
|
||||
|
||||
export function fromId(id: string, version?: string): URI {
|
||||
if (typeof version === 'string') {
|
||||
return new URI().withScheme(VSCodeExtensionUri.SCHEME).withAuthority(id).withPath(`/${version}`);
|
||||
} else {
|
||||
return new URI().withScheme(VSCodeExtensionUri.SCHEME).withAuthority(id);
|
||||
}
|
||||
}
|
||||
|
||||
export function fromVersionedId(versionedId: string): URI {
|
||||
const versionAndId = versionedId.split('@');
|
||||
return fromId(versionAndId[0], versionAndId[1]);
|
||||
}
|
||||
|
||||
export function toId(uri: URI): { id: string, version?: string } | undefined {
|
||||
if (uri.scheme === VSCodeExtensionUri.SCHEME) {
|
||||
return { id: uri.authority, version: uri.path.isRoot ? undefined : uri.path.base };
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2022 Arm and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const _scope = (this as any);
|
||||
_scope.exports = {};
|
||||
|
||||
const _getModule = () => {
|
||||
if (!_scope[_scope.frontendModuleName]) {
|
||||
_scope[_scope.frontendModuleName] = {};
|
||||
}
|
||||
return _scope[_scope.frontendModuleName];
|
||||
};
|
||||
|
||||
Object.defineProperty(_scope.exports, 'activate', {
|
||||
set: value => _getModule().activate = value
|
||||
});
|
||||
|
||||
Object.defineProperty(_scope.exports, 'deactivate', {
|
||||
set: value => _getModule().deactivate = value
|
||||
});
|
||||
|
||||
_scope.require = (moduleName: string) => {
|
||||
const vscodeModuleName = 'vscode';
|
||||
|
||||
if (moduleName === vscodeModuleName) {
|
||||
// Return the defaultApi
|
||||
return _scope.theia._empty;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2018 Red Hat, Inc. and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import * as path from 'path';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { PluginDeployerResolverContext } from '@theia/plugin-ext';
|
||||
import { LocalPluginDeployerResolver } from '@theia/plugin-ext/lib/main/node/resolvers/local-plugin-deployer-resolver';
|
||||
import { PluginVSCodeEnvironment } from '../common/plugin-vscode-environment';
|
||||
import { isVSCodePluginFile } from './plugin-vscode-file-handler';
|
||||
import { existsInDeploymentDir, unpackToDeploymentDir } from './plugin-vscode-utils';
|
||||
|
||||
@injectable()
|
||||
export class LocalVSIXFilePluginDeployerResolver extends LocalPluginDeployerResolver {
|
||||
static LOCAL_FILE = 'local-file';
|
||||
static FILE_EXTENSION = '.vsix';
|
||||
|
||||
@inject(PluginVSCodeEnvironment) protected readonly environment: PluginVSCodeEnvironment;
|
||||
|
||||
protected get supportedScheme(): string {
|
||||
return LocalVSIXFilePluginDeployerResolver.LOCAL_FILE;
|
||||
}
|
||||
|
||||
override accept(pluginId: string): boolean {
|
||||
return super.accept(pluginId) && isVSCodePluginFile(pluginId);
|
||||
}
|
||||
|
||||
async resolveFromLocalPath(pluginResolverContext: PluginDeployerResolverContext, localPath: string): Promise<void> {
|
||||
const extensionId = path.basename(localPath, LocalVSIXFilePluginDeployerResolver.FILE_EXTENSION);
|
||||
|
||||
if (await existsInDeploymentDir(this.environment, extensionId)) {
|
||||
console.log(`[${pluginResolverContext.getOriginId()}]: Target dir already exists in plugin deployment dir`);
|
||||
return;
|
||||
}
|
||||
|
||||
const extensionDeploymentDir = await unpackToDeploymentDir(this.environment, localPath, extensionId);
|
||||
pluginResolverContext.addPlugin(extensionId, extensionDeploymentDir);
|
||||
}
|
||||
}
|
||||
28
packages/plugin-ext-vscode/src/node/package.spec.ts
Normal file
28
packages/plugin-ext-vscode/src/node/package.spec.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2018 Red Hat, Inc. and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
/* note: this bogus test file is required so that
|
||||
we are able to run mocha unit tests on this
|
||||
package, without having any actual unit tests in it.
|
||||
This way a coverage report will be generated,
|
||||
showing 0% coverage, instead of no report.
|
||||
This file can be removed once we have real unit
|
||||
tests in place. */
|
||||
|
||||
describe('plugin-ext-vscode package', () => {
|
||||
|
||||
it('support code coverage statistics', () => true);
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2018 Red Hat, Inc. and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { ContainerModule } from '@theia/core/shared/inversify';
|
||||
import {
|
||||
PluginDeployerFileHandler, PluginDeployerDirectoryHandler, PluginScanner, PluginDeployerParticipant, PluginDeployerResolver
|
||||
} from '@theia/plugin-ext';
|
||||
import { PluginVsCodeFileHandler } from './plugin-vscode-file-handler';
|
||||
import { PluginVsCodeDirectoryHandler } from './plugin-vscode-directory-handler';
|
||||
import { VsCodePluginScanner } from './scanner-vscode';
|
||||
import { PluginVsCodeCliContribution } from './plugin-vscode-cli-contribution';
|
||||
import { CliContribution } from '@theia/core/lib/node';
|
||||
import { PluginHostEnvironmentVariable } from '@theia/plugin-ext/lib/common';
|
||||
import { PluginVSCodeEnvironment } from '../common/plugin-vscode-environment';
|
||||
import { PluginVSCodeDeployerParticipant } from './plugin-vscode-deployer-participant';
|
||||
import { LocalVSIXFilePluginDeployerResolver } from './local-vsix-file-plugin-deployer-resolver';
|
||||
|
||||
export default new ContainerModule(bind => {
|
||||
bind(PluginVSCodeEnvironment).toSelf().inSingletonScope();
|
||||
|
||||
bind(PluginVSCodeDeployerParticipant).toSelf().inSingletonScope();
|
||||
bind(PluginDeployerParticipant).toService(PluginVSCodeDeployerParticipant);
|
||||
|
||||
bind(PluginDeployerFileHandler).to(PluginVsCodeFileHandler).inSingletonScope();
|
||||
bind(PluginDeployerDirectoryHandler).to(PluginVsCodeDirectoryHandler).inSingletonScope();
|
||||
bind(PluginScanner).to(VsCodePluginScanner).inSingletonScope();
|
||||
|
||||
bind(PluginVsCodeCliContribution).toSelf().inSingletonScope();
|
||||
bind(CliContribution).toService(PluginVsCodeCliContribution);
|
||||
bind(PluginHostEnvironmentVariable).toService(PluginVsCodeCliContribution);
|
||||
|
||||
bind(PluginDeployerResolver).to(LocalVSIXFilePluginDeployerResolver).inSingletonScope();
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2019 Red Hat, Inc. and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { Argv, Arguments } from '@theia/core/shared/yargs';
|
||||
import { CliContribution } from '@theia/core/lib/node/cli';
|
||||
import { PluginHostEnvironmentVariable } from '@theia/plugin-ext/lib/common';
|
||||
import { VSCODE_DEFAULT_API_VERSION } from '../common/plugin-vscode-types';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
|
||||
/**
|
||||
* CLI Contribution allowing to override the VS Code API version which is returned by `vscode.version` API call.
|
||||
*/
|
||||
@injectable()
|
||||
export class PluginVsCodeCliContribution implements CliContribution, PluginHostEnvironmentVariable {
|
||||
|
||||
/**
|
||||
* CLI argument name to define the supported VS Code API version.
|
||||
*/
|
||||
static VSCODE_API_VERSION = 'vscode-api-version';
|
||||
|
||||
protected vsCodeApiVersion?: string;
|
||||
protected vsCodeApiVersionDeferred = new Deferred<string>();
|
||||
|
||||
get vsCodeApiVersionPromise(): Promise<string> {
|
||||
return this.vsCodeApiVersionDeferred.promise;
|
||||
}
|
||||
|
||||
configure(conf: Argv): void {
|
||||
conf.option(PluginVsCodeCliContribution.VSCODE_API_VERSION, {
|
||||
// eslint-disable-next-line max-len
|
||||
description: `Overrides the version returned by VSCode API 'vscode.version'. Example: --${PluginVsCodeCliContribution.VSCODE_API_VERSION}=<Wanted Version>. Default [${VSCODE_DEFAULT_API_VERSION}]`,
|
||||
type: 'string',
|
||||
nargs: 1
|
||||
});
|
||||
}
|
||||
|
||||
setArguments(args: Arguments): void {
|
||||
const arg = args[PluginVsCodeCliContribution.VSCODE_API_VERSION] as string | undefined;
|
||||
this.vsCodeApiVersion = arg?.trim() || process.env['VSCODE_API_VERSION']?.trim() || VSCODE_DEFAULT_API_VERSION;
|
||||
process.env['VSCODE_API_VERSION'] = this.vsCodeApiVersion;
|
||||
this.vsCodeApiVersionDeferred.resolve(this.vsCodeApiVersion);
|
||||
}
|
||||
|
||||
process(env: NodeJS.ProcessEnv): void {
|
||||
if (this.vsCodeApiVersion) {
|
||||
env['VSCODE_API_VERSION'] = this.vsCodeApiVersion;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2020 TypeFox and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
||||
import * as fs from '@theia/core/shared/fs-extra';
|
||||
import { FileUri } from '@theia/core/lib/node';
|
||||
import { PluginVSCodeEnvironment } from '../common/plugin-vscode-environment';
|
||||
import { PluginDeployerParticipant, PluginDeployerStartContext } from '@theia/plugin-ext/lib/common/plugin-protocol';
|
||||
import { LocalVSIXFilePluginDeployerResolver } from './local-vsix-file-plugin-deployer-resolver';
|
||||
|
||||
@injectable()
|
||||
export class PluginVSCodeDeployerParticipant implements PluginDeployerParticipant {
|
||||
|
||||
@inject(PluginVSCodeEnvironment)
|
||||
protected readonly environments: PluginVSCodeEnvironment;
|
||||
|
||||
async onWillStart(context: PluginDeployerStartContext): Promise<void> {
|
||||
const extensionDeploymentDirUri = await this.environments.getDeploymentDirUri();
|
||||
context.userEntries.push(extensionDeploymentDirUri.withScheme('local-dir').toString());
|
||||
|
||||
const userExtensionDirUri = await this.environments.getUserExtensionsDirUri();
|
||||
const userExtensionDirPath = FileUri.fsPath(userExtensionDirUri);
|
||||
|
||||
if (await fs.pathExists(userExtensionDirPath)) {
|
||||
const files = await fs.readdir(userExtensionDirPath);
|
||||
for (const file of files) {
|
||||
if (file.endsWith(LocalVSIXFilePluginDeployerResolver.FILE_EXTENSION)) {
|
||||
const extensionUri = userExtensionDirUri.resolve(file).withScheme('local-file').toString();
|
||||
console.log(`found drop-in extension "${extensionUri}"`);
|
||||
context.userEntries.push(extensionUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2018 Red Hat, Inc. and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import * as path from 'path';
|
||||
import * as fs from '@theia/core/shared/fs-extra';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import type { RecursivePartial, URI } from '@theia/core';
|
||||
import { Deferred, firstTrue } from '@theia/core/lib/common/promise-util';
|
||||
import {
|
||||
PluginDeployerDirectoryHandler, PluginDeployerEntry, PluginDeployerDirectoryHandlerContext,
|
||||
PluginDeployerEntryType, PluginPackage, PluginIdentifiers
|
||||
} from '@theia/plugin-ext';
|
||||
import { PluginCliContribution } from '@theia/plugin-ext/lib/main/node/plugin-cli-contribution';
|
||||
import { TMP_DIR_PREFIX } from './plugin-vscode-utils';
|
||||
|
||||
@injectable()
|
||||
export class PluginVsCodeDirectoryHandler implements PluginDeployerDirectoryHandler {
|
||||
|
||||
protected readonly deploymentDirectory: Deferred<URI>;
|
||||
|
||||
@inject(PluginCliContribution) protected readonly pluginCli: PluginCliContribution;
|
||||
|
||||
async accept(plugin: PluginDeployerEntry): Promise<boolean> {
|
||||
console.debug(`Resolving "${plugin.id()}" as a VS Code extension...`);
|
||||
if (plugin.path().startsWith(TMP_DIR_PREFIX)) {
|
||||
// avoid adding corrupted plugins from temporary directories
|
||||
return false;
|
||||
}
|
||||
return this.attemptResolution(plugin);
|
||||
}
|
||||
|
||||
protected async attemptResolution(plugin: PluginDeployerEntry): Promise<boolean> {
|
||||
if (this.resolvePackage(plugin)) {
|
||||
return true;
|
||||
}
|
||||
return this.deriveMetadata(plugin);
|
||||
}
|
||||
|
||||
protected async deriveMetadata(plugin: PluginDeployerEntry): Promise<boolean> {
|
||||
return firstTrue(
|
||||
this.resolveFromSources(plugin),
|
||||
this.resolveFromVSIX(plugin),
|
||||
this.resolveFromNpmTarball(plugin)
|
||||
);
|
||||
}
|
||||
|
||||
async handle(context: PluginDeployerDirectoryHandlerContext): Promise<void> {
|
||||
const types: PluginDeployerEntryType[] = [];
|
||||
const packageJson: PluginPackage = context.pluginEntry().getValue('package.json');
|
||||
if (packageJson.browser) {
|
||||
types.push(PluginDeployerEntryType.FRONTEND);
|
||||
}
|
||||
if (packageJson.main || !packageJson.browser) {
|
||||
types.push(PluginDeployerEntryType.BACKEND);
|
||||
}
|
||||
context.pluginEntry().accept(...types);
|
||||
}
|
||||
|
||||
protected async resolveFromSources(plugin: PluginDeployerEntry): Promise<boolean> {
|
||||
const pluginPath = plugin.path();
|
||||
const pck = await this.requirePackage(pluginPath);
|
||||
return this.resolvePackage(plugin, { pluginPath, pck });
|
||||
}
|
||||
|
||||
protected async resolveFromVSIX(plugin: PluginDeployerEntry): Promise<boolean> {
|
||||
if (!(await fs.pathExists(path.join(plugin.path(), 'extension.vsixmanifest')))) {
|
||||
return false;
|
||||
}
|
||||
const pluginPath = path.join(plugin.path(), 'extension');
|
||||
const pck = await this.requirePackage(pluginPath);
|
||||
return this.resolvePackage(plugin, { pluginPath, pck });
|
||||
}
|
||||
|
||||
protected async resolveFromNpmTarball(plugin: PluginDeployerEntry): Promise<boolean> {
|
||||
const pluginPath = path.join(plugin.path(), 'package');
|
||||
const pck = await this.requirePackage(pluginPath);
|
||||
return this.resolvePackage(plugin, { pluginPath, pck });
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
pck.publisher ??= PluginIdentifiers.UNPUBLISHED;
|
||||
if (options) {
|
||||
plugin.storeValue('package.json', pck);
|
||||
plugin.rootPath = plugin.path();
|
||||
plugin.updatePath(pluginPath);
|
||||
}
|
||||
console.debug(`Resolved "${plugin.id()}" to a VS Code extension "${pck.name}@${pck.version}" with engines:`, pck.engines);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected async requirePackage(pluginPath: string): Promise<PluginPackage | undefined> {
|
||||
try {
|
||||
const plugin: PluginPackage = await fs.readJSON(path.join(pluginPath, 'package.json'));
|
||||
plugin.publisher ??= PluginIdentifiers.UNPUBLISHED;
|
||||
return plugin;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2018 Red Hat, Inc. and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import { PluginDeployerFileHandler, PluginDeployerEntry, PluginDeployerFileHandlerContext } from '@theia/plugin-ext';
|
||||
import * as filenamify from 'filenamify';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import * as fs from '@theia/core/shared/fs-extra';
|
||||
import { PluginVSCodeEnvironment } from '../common/plugin-vscode-environment';
|
||||
import { FileUri } from '@theia/core/lib/common/file-uri';
|
||||
import { unpackToDeploymentDir } from './plugin-vscode-utils';
|
||||
|
||||
export const isVSCodePluginFile = (pluginPath?: string) => Boolean(pluginPath && (pluginPath.endsWith('.vsix') || pluginPath.endsWith('.tgz')));
|
||||
|
||||
@injectable()
|
||||
export class PluginVsCodeFileHandler implements PluginDeployerFileHandler {
|
||||
@inject(PluginVSCodeEnvironment)
|
||||
protected readonly environment: PluginVSCodeEnvironment;
|
||||
|
||||
async accept(resolvedPlugin: PluginDeployerEntry): Promise<boolean> {
|
||||
return resolvedPlugin.isFile().then(file => {
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
return isVSCodePluginFile(resolvedPlugin.path());
|
||||
});
|
||||
}
|
||||
|
||||
async handle(context: PluginDeployerFileHandlerContext): Promise<void> {
|
||||
const id = this.getNormalizedExtensionId(context.pluginEntry().id());
|
||||
const extensionDeploymentDir = await unpackToDeploymentDir(this.environment, context.pluginEntry().path(), id);
|
||||
context.pluginEntry().updatePath(extensionDeploymentDir);
|
||||
console.log(`root path: ${context.pluginEntry().rootPath}`);
|
||||
const originalPath = context.pluginEntry().originalPath();
|
||||
if (originalPath && originalPath !== extensionDeploymentDir) {
|
||||
const tempDirUri = await this.environment.getTempDirUri();
|
||||
if (originalPath.startsWith(FileUri.fsPath(tempDirUri))) {
|
||||
try {
|
||||
await fs.remove(FileUri.fsPath(originalPath));
|
||||
} catch (e) {
|
||||
console.error(`[${id}]: failed to remove temporary files: "${originalPath}"`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected getNormalizedExtensionId(pluginId: string): string {
|
||||
return filenamify(pluginId, { replacement: '_' }).replace(/\.vsix$/, '');
|
||||
}
|
||||
}
|
||||
80
packages/plugin-ext-vscode/src/node/plugin-vscode-init.ts
Normal file
80
packages/plugin-ext-vscode/src/node/plugin-vscode-init.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2018-2019 Red Hat, Inc.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
import * as theia from '@theia/plugin';
|
||||
import { BackendInitializationFn, PluginAPIFactory, Plugin, emptyPlugin } from '@theia/plugin-ext';
|
||||
import { VSCODE_DEFAULT_API_VERSION } from '../common/plugin-vscode-types';
|
||||
|
||||
process.env['VSCODE_PID'] = process.env['THEIA_PARENT_PID'];
|
||||
|
||||
const pluginsApiImpl = new Map<string, typeof theia>();
|
||||
const plugins = new Array<Plugin>();
|
||||
let defaultApi: typeof theia;
|
||||
let isLoadOverride = false;
|
||||
let pluginApiFactory: PluginAPIFactory;
|
||||
|
||||
export const doInitialization: BackendInitializationFn = (apiFactory: PluginAPIFactory, plugin: Plugin) => {
|
||||
pluginsApiImpl.set(plugin.model.id, createVSCodeAPI(apiFactory, plugin));
|
||||
plugins.push(plugin);
|
||||
pluginApiFactory = apiFactory;
|
||||
|
||||
if (!isLoadOverride) {
|
||||
overrideInternalLoad();
|
||||
isLoadOverride = true;
|
||||
}
|
||||
};
|
||||
|
||||
function createVSCodeAPI(apiFactory: PluginAPIFactory, plugin: Plugin): typeof theia {
|
||||
const vscode = apiFactory(plugin);
|
||||
|
||||
// override the version for vscode to be a VSCode version
|
||||
(<any>vscode).version = process.env['VSCODE_API_VERSION'] || VSCODE_DEFAULT_API_VERSION;
|
||||
return vscode;
|
||||
}
|
||||
|
||||
function overrideInternalLoad(): void {
|
||||
const module = require('module');
|
||||
const vscodeModuleName = 'vscode';
|
||||
// save original load method
|
||||
const internalLoad = module._load;
|
||||
|
||||
// if we try to resolve theia module, return the filename entry to use cache.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
module._load = function (request: string, parent: any, isMain: {}): any {
|
||||
if (request !== vscodeModuleName) {
|
||||
return internalLoad.apply(this, arguments);
|
||||
}
|
||||
|
||||
const plugin = findPlugin(parent.filename);
|
||||
if (plugin) {
|
||||
const apiImpl = pluginsApiImpl.get(plugin.model.id);
|
||||
return apiImpl;
|
||||
}
|
||||
|
||||
if (!defaultApi) {
|
||||
console.warn(`Could not identify plugin for 'Theia' require call from ${parent.filename}`);
|
||||
defaultApi = createVSCodeAPI(pluginApiFactory, emptyPlugin);
|
||||
}
|
||||
|
||||
return defaultApi;
|
||||
};
|
||||
}
|
||||
|
||||
function findPlugin(filePath: string): Plugin | undefined {
|
||||
return plugins.find(plugin => filePath.startsWith(plugin.pluginFolder));
|
||||
}
|
||||
101
packages/plugin-ext-vscode/src/node/plugin-vscode-utils.ts
Normal file
101
packages/plugin-ext-vscode/src/node/plugin-vscode-utils.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2023 STMicroelectronics and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import * as decompress from 'decompress';
|
||||
import * as path from 'path';
|
||||
import * as filenamify from 'filenamify';
|
||||
import { FileUri } from '@theia/core/lib/node';
|
||||
import * as fs from '@theia/core/shared/fs-extra';
|
||||
import { PluginVSCodeEnvironment } from '../common/plugin-vscode-environment';
|
||||
|
||||
export async function decompressExtension(sourcePath: string, destPath: string): Promise<boolean> {
|
||||
try {
|
||||
await decompress(sourcePath, destPath);
|
||||
if (sourcePath.endsWith('.tgz')) {
|
||||
// unzip node_modules from built-in extensions, see https://github.com/eclipse-theia/theia/issues/5756
|
||||
const extensionPath = path.join(destPath, 'package');
|
||||
const vscodeNodeModulesPath = path.join(extensionPath, 'vscode_node_modules.zip');
|
||||
if (await fs.pathExists(vscodeNodeModulesPath)) {
|
||||
await decompress(vscodeNodeModulesPath, path.join(extensionPath, 'node_modules'));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`Failed to decompress ${sourcePath} to ${destPath}: ${error}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function existsInDeploymentDir(env: PluginVSCodeEnvironment, extensionId: string): Promise<boolean> {
|
||||
return fs.pathExists(await getExtensionDeploymentDir(env, extensionId));
|
||||
}
|
||||
|
||||
export const TMP_DIR_PREFIX = 'tmp-vscode-unpacked-';
|
||||
export async function unpackToDeploymentDir(env: PluginVSCodeEnvironment, sourcePath: string, extensionId: string): Promise<string> {
|
||||
const extensionDeploymentDir = await getExtensionDeploymentDir(env, extensionId);
|
||||
if (await fs.pathExists(extensionDeploymentDir)) {
|
||||
console.log(`[${extensionId}]: deployment dir "${extensionDeploymentDir}" already exists`);
|
||||
return extensionDeploymentDir;
|
||||
}
|
||||
|
||||
const tempDir = await getTempDir(env, TMP_DIR_PREFIX);
|
||||
try {
|
||||
console.log(`[${extensionId}]: trying to decompress "${sourcePath}" into "${tempDir}"...`);
|
||||
if (!await decompressExtension(sourcePath, tempDir)) {
|
||||
await fs.remove(tempDir);
|
||||
const msg = `[${extensionId}]: decompressing "${sourcePath}" to "${tempDir}" failed`;
|
||||
console.error(msg);
|
||||
throw new Error(msg);
|
||||
}
|
||||
} catch (e) {
|
||||
await fs.remove(tempDir);
|
||||
const msg = `[${extensionId}]: error while decompressing "${sourcePath}" to "${tempDir}"`;
|
||||
console.error(msg, e);
|
||||
throw e;
|
||||
}
|
||||
console.log(`[${extensionId}]: decompressed to temp dir "${tempDir}"`);
|
||||
|
||||
try {
|
||||
console.log(`[${extensionId}]: renaming to extension dir "${extensionDeploymentDir}"...`);
|
||||
await fs.rename(tempDir, extensionDeploymentDir);
|
||||
return extensionDeploymentDir;
|
||||
} catch (e) {
|
||||
await fs.remove(tempDir);
|
||||
console.error(`[${extensionId}]: error while renaming "${tempDir}" to "${extensionDeploymentDir}"`, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getExtensionDeploymentDir(env: PluginVSCodeEnvironment, extensionId: string): Promise<string> {
|
||||
const deployedPluginsDirUri = await env.getDeploymentDirUri();
|
||||
const normalizedExtensionId = filenamify(extensionId, { replacement: '_' });
|
||||
const extensionDeploymentDirPath = FileUri.fsPath(deployedPluginsDirUri.resolve(normalizedExtensionId));
|
||||
return extensionDeploymentDirPath;
|
||||
}
|
||||
|
||||
export async function getTempDir(env: PluginVSCodeEnvironment, prefix: string): Promise<string> {
|
||||
const deploymentDirPath = FileUri.fsPath(await env.getDeploymentDirUri());
|
||||
try {
|
||||
if (!await fs.pathExists(deploymentDirPath)) {
|
||||
console.log(`Creating deployment dir ${deploymentDirPath}`);
|
||||
await fs.mkdirs(deploymentDirPath);
|
||||
}
|
||||
return await fs.mkdtemp(path.join(deploymentDirPath, prefix));
|
||||
} catch (error) {
|
||||
console.error(`Failed to create deployment dir ${deploymentDirPath}: ${error}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
113
packages/plugin-ext-vscode/src/node/scanner-vscode.ts
Normal file
113
packages/plugin-ext-vscode/src/node/scanner-vscode.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2015-2021 Red Hat, Inc.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import * as path from 'path';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { PluginScanner, PluginEngine, PluginPackage, PluginModel, PluginLifecycle, PluginEntryPoint, buildFrontendModuleName, UIKind, PluginIdentifiers } from '@theia/plugin-ext';
|
||||
import { TheiaPluginScanner } from '@theia/plugin-ext/lib/hosted/node/scanners/scanner-theia';
|
||||
import { environment } from '@theia/core/shared/@theia/application-package/lib/environment';
|
||||
import { VSCodeExtensionUri } from '../common/plugin-vscode-uri';
|
||||
|
||||
const uiKind = environment.electron.is() ? UIKind.Desktop : UIKind.Web;
|
||||
|
||||
@injectable()
|
||||
export class VsCodePluginScanner extends TheiaPluginScanner implements PluginScanner {
|
||||
|
||||
private readonly VSCODE_TYPE: PluginEngine = 'vscode';
|
||||
|
||||
override get apiType(): PluginEngine {
|
||||
return this.VSCODE_TYPE;
|
||||
}
|
||||
|
||||
override getModel(plugin: PluginPackage): PluginModel {
|
||||
// publisher can be empty on vscode extension development
|
||||
const publisher = plugin.publisher ?? PluginIdentifiers.UNPUBLISHED;
|
||||
|
||||
// Only one entrypoint is valid in vscode extensions
|
||||
// Mimic choosing frontend (web extension) and backend (local/remote extension) as described here:
|
||||
// https://code.visualstudio.com/api/advanced-topics/extension-host#preferred-extension-location
|
||||
const entryPoint: PluginEntryPoint = {};
|
||||
|
||||
// Act like codespaces when run in the browser (UIKind === 'web' and extensionKind is ['ui'])
|
||||
const preferFrontend = uiKind === UIKind.Web && (plugin.extensionKind?.length === 1 && plugin.extensionKind[0] === 'ui');
|
||||
|
||||
if (plugin.browser && (!plugin.main || preferFrontend)) {
|
||||
// Use frontend if available and there is no backend or frontend is preferred
|
||||
entryPoint.frontend = plugin.browser;
|
||||
} else {
|
||||
// Default to using backend
|
||||
entryPoint.backend = plugin.main;
|
||||
}
|
||||
if (plugin.theiaPlugin?.headless) {
|
||||
// Support the Theia-specific extension for headless plugins
|
||||
entryPoint.headless = plugin.theiaPlugin?.headless;
|
||||
}
|
||||
|
||||
const result: PluginModel = {
|
||||
packagePath: plugin.packagePath,
|
||||
packageUri: this.pluginUriFactory.createUri(plugin).toString(),
|
||||
// see id definition: https://github.com/microsoft/vscode/blob/15916055fe0cb9411a5f36119b3b012458fe0a1d/src/vs/platform/extensions/common/extensions.ts#L167-L169
|
||||
id: `${publisher.toLowerCase()}.${plugin.name.toLowerCase()}`,
|
||||
name: plugin.name,
|
||||
publisher: publisher,
|
||||
version: plugin.version,
|
||||
displayName: plugin.displayName,
|
||||
description: plugin.description,
|
||||
engine: {
|
||||
type: this.VSCODE_TYPE,
|
||||
version: plugin.engines[this.VSCODE_TYPE]
|
||||
},
|
||||
entryPoint,
|
||||
iconUrl: plugin.icon && PluginPackage.toPluginUrl(plugin, plugin.icon),
|
||||
l10n: plugin.l10n,
|
||||
readmeUrl: this.getReadmeUrl(plugin),
|
||||
licenseUrl: this.getLicenseUrl(plugin)
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps extension dependencies to deployable extension dependencies.
|
||||
*/
|
||||
override getDependencies(plugin: PluginPackage): Map<string, string> | undefined {
|
||||
// Store the list of dependencies.
|
||||
const dependencies = new Map<string, string>();
|
||||
// Iterate through the list of dependencies from `extensionDependencies` and `extensionPack`.
|
||||
for (const dependency of [plugin.extensionDependencies, plugin.extensionPack]) {
|
||||
if (dependency !== undefined) {
|
||||
// Iterate over the list of dependencies present, and add them to the collection.
|
||||
dependency.forEach((dep: string) => {
|
||||
const dependencyId = dep.toLowerCase();
|
||||
dependencies.set(dependencyId, VSCodeExtensionUri.fromId(dependencyId).toString());
|
||||
});
|
||||
}
|
||||
}
|
||||
// Return the map of dependencies if present, else `undefined`.
|
||||
return dependencies.size > 0 ? dependencies : undefined;
|
||||
}
|
||||
|
||||
override getLifecycle(plugin: PluginPackage): PluginLifecycle {
|
||||
return {
|
||||
startMethod: 'activate',
|
||||
stopMethod: 'deactivate',
|
||||
frontendModuleName: buildFrontendModuleName(plugin),
|
||||
|
||||
frontendInitPath: 'plugin-vscode-init-fe.js',
|
||||
backendInitPath: path.join(__dirname, 'plugin-vscode-init'),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
60
packages/plugin-ext-vscode/tsconfig.json
Normal file
60
packages/plugin-ext-vscode/tsconfig.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"extends": "../../configs/base.tsconfig",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"rootDir": "src",
|
||||
"outDir": "lib",
|
||||
"lib": [
|
||||
"es6",
|
||||
"dom",
|
||||
"webworker"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../callhierarchy"
|
||||
},
|
||||
{
|
||||
"path": "../core"
|
||||
},
|
||||
{
|
||||
"path": "../editor"
|
||||
},
|
||||
{
|
||||
"path": "../filesystem"
|
||||
},
|
||||
{
|
||||
"path": "../monaco"
|
||||
},
|
||||
{
|
||||
"path": "../navigator"
|
||||
},
|
||||
{
|
||||
"path": "../outline-view"
|
||||
},
|
||||
{
|
||||
"path": "../plugin"
|
||||
},
|
||||
{
|
||||
"path": "../plugin-ext"
|
||||
},
|
||||
{
|
||||
"path": "../scm"
|
||||
},
|
||||
{
|
||||
"path": "../terminal"
|
||||
},
|
||||
{
|
||||
"path": "../typehierarchy"
|
||||
},
|
||||
{
|
||||
"path": "../userstorage"
|
||||
},
|
||||
{
|
||||
"path": "../workspace"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user