Skip to content

Commit

Permalink
Fix VSCode marketplace release (#106)
Browse files Browse the repository at this point in the history
* Use custom tree-kill

* Use deactivate event

* Resolve after kill in windows

* Update README.md
  • Loading branch information
haydar-metin authored Apr 17, 2023
1 parent 1420a38 commit 05f99fa
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 47 deletions.
8 changes: 4 additions & 4 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"nohoist": [
"**/path",
"**/path/**",
"biguml-vscode/@vscode/codicons",
"biguml-vscode/@vscode/codicons/**"
"umldiagram/@vscode/codicons",
"umldiagram/@vscode/codicons/**"
]
},
"scripts": {
Expand All @@ -21,11 +21,11 @@
"package:zip": "yarn package && cd ${INIT_CWD} && zip -r ./release-$(date +%Y%m%d-%H%M).zip ./release",
"prepare": "lerna run prepare",
"prepare:theia": "yarn prepare --include-dependencies=true --scope=biguml-theia",
"prepare:vscode": "yarn prepare --include-dependencies=true --scope=biguml-vscode",
"prepare:vscode": "yarn prepare --include-dependencies=true --scope=umldiagram",
"start:theia:debug": "cd environments/theia-app && yarn start:debug",
"watch": "lerna run --parallel watch",
"watch:theia": "yarn watch --include-dependencies=true --scope=biguml-theia",
"watch:vscode": "yarn watch --include-dependencies=true --scope=biguml-vscode"
"watch:vscode": "yarn watch --include-dependencies=true --scope=umldiagram"
},
"resolutions": {
"**/@eclipse-emfcloud/modelserver-theia": "0.8.0-theia-cr02",
Expand Down
4 changes: 2 additions & 2 deletions client/packages/uml-vscode-integration/extension/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
> [Open-source](https://github.com/borkdominik/bigUML) **UML Modeling Tool** for [Visual Studio Code](https://code.visualstudio.com/) supporting graphical editing diagrams.
<p align="center">
<img src="./resources/biguml-vscode.png" alt="Demo" width="800" />
<img src="https://user-images.githubusercontent.com/13104167/232125930-af3158e7-397f-4ba6-9d57-e76530b075d0.png" alt="Demo" width="800" />
</p>

<br />
Expand Down Expand Up @@ -47,4 +47,4 @@ _In the background two Java-based language servers will be started._

You can create a new model by either using the command `bigUML: New Empty UML Diagram` or with `File -> New File`.

![New File Command](./resources/new-model-command.png)
![New File command](https://user-images.githubusercontent.com/13104167/232125866-db586183-59b9-47a3-8b95-b54a85c1c676.png)
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@
"@vscode/codicons": "^0.0.25",
"inversify": "5.1.1",
"reflect-metadata": "^0.1.13",
"tree-kill": "^1.2.2",
"urijs": "^1.19.11"
},
"devDependencies": {
Expand Down
33 changes: 22 additions & 11 deletions client/packages/uml-vscode-integration/extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,20 @@
import '../css/colors.css';

import { ModelServerConfig } from '@borkdominik-biguml/uml-modelserver/lib/config';
import { Container } from 'inversify';
import * as vscode from 'vscode';
import { createContainer } from './di.config';
import { TYPES, VSCODE_TYPES } from './di.types';
import { UVGlspConnector } from './glsp/connection/uv-glsp-connector';
import { UVGlspServer } from './glsp/connection/uv-glsp-server';
import { GlspServerConfig, launchGLSPServer } from './glsp/launcher/glsp-server-launcher';
import { GlspServerConfig, launchGLSPServer, UmlGLSPServerLauncher } from './glsp/launcher/glsp-server-launcher';
import { VSCodeSettings } from './language';
import { launchModelServer } from './modelserver/launcher/modelserver-launcher';
import { launchModelServer, ModelServerLauncher } from './modelserver/launcher/modelserver-launcher';
import { freePort } from './utils/server';
import { configureDefaultCommands } from './vscode/command/default-commands';

const modelServerRoute = '/api/v2/';
let diContainer: Container | undefined;

export async function activate(context: vscode.ExtensionContext): Promise<void> {
const glspServerConfig: GlspServerConfig = {
Expand All @@ -41,28 +43,37 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
url: `http://localhost:${modelServerPort}${modelServerRoute}`
};

const container = createContainer(context, {
diContainer = createContainer(context, {
glspServerConfig,
modelServerConfig
});

if (process.env.UML_MODEL_SERVER_DEBUG !== 'true') {
await launchModelServer(container, modelServerConfig);
await launchModelServer(diContainer, modelServerConfig);
}

if (process.env.UML_GLSP_SERVER_DEBUG !== 'true') {
await launchGLSPServer(container, glspServerConfig);
await launchGLSPServer(diContainer, glspServerConfig);
}

configureDefaultCommands({
extensionContext: context,
connector: container.get<UVGlspConnector>(TYPES.Connector),
connector: diContainer.get<UVGlspConnector>(TYPES.Connector),
diagramPrefix: VSCodeSettings.commands.prefix
});

container.getAll<any>(VSCODE_TYPES.Watcher);
container.get<any>(VSCODE_TYPES.EditorProvider);
container.get<any>(VSCODE_TYPES.CommandManager);
container.get<any>(VSCODE_TYPES.DisposableManager);
container.get<UVGlspServer>(TYPES.GlspServer).start();
diContainer.getAll<any>(VSCODE_TYPES.Watcher);
diContainer.get<any>(VSCODE_TYPES.EditorProvider);
diContainer.get<any>(VSCODE_TYPES.CommandManager);
diContainer.get<any>(VSCODE_TYPES.DisposableManager);
diContainer.get<UVGlspServer>(TYPES.GlspServer).start();
}

export async function deactivate(context: vscode.ExtensionContext): Promise<any> {
if (diContainer) {
return Promise.all([
diContainer.get<UmlGLSPServerLauncher>(TYPES.GlspServerLauncher).stop(),
diContainer.get<ModelServerLauncher>(TYPES.ModelServerLauncher).stop()
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import * as fs from 'fs';
import { Container, inject, injectable } from 'inversify';
import * as net from 'net';
import * as path from 'path';
import kill from 'tree-kill';
import { TYPES, VSCODE_TYPES } from '../../di.types';
import { kill } from '../../utils/process';
import { OutputChannel } from '../../vscode/output/output.channel';

const START_UP_COMPLETE_MSG = 'Startup completed';
Expand Down Expand Up @@ -119,7 +119,9 @@ export class UmlGLSPServerLauncher extends GlspServerLauncher {
if (this.options.socketConnectionOptions.host) {
args.push('--host', `${this.options.socketConnectionOptions.host}`);
}
return childProcess.spawn('java', args);
return childProcess.spawn('java', args, {
detached: false
});
}

protected override handleStdoutData(data: string | Buffer): void {
Expand All @@ -142,13 +144,13 @@ export class UmlGLSPServerLauncher extends GlspServerLauncher {
throw error;
}

override stop(): void {
if (this.serverProcess && this.serverProcess.pid && !this.serverProcess.killed) {
kill(this.serverProcess.pid, 'SIGINT', error => console.error('Error', error));
override dispose(): void {
// No op
}

if (!this.serverProcess.killed) {
this.serverProcess.kill('SIGINT');
}
override async stop(): Promise<void> {
if (this.serverProcess && this.serverProcess.pid && !this.serverProcess.killed) {
await kill(this.serverProcess.pid, 'SIGINT');
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@
********************************************************************************/
import 'reflect-metadata';
import * as vscode from 'vscode';
import { activate as extensionActivate } from './extension';
import { activate as extensionActivate, deactivate as extensionDeactivate } from './extension';

export function activate(context: vscode.ExtensionContext): Promise<void> {
return extensionActivate(context);
}

export function deactivate(context: vscode.ExtensionContext): Promise<void> {
return extensionDeactivate(context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import * as fs from 'fs';
import { Container, inject, injectable } from 'inversify';
import * as net from 'net';
import * as path from 'path';
import kill from 'tree-kill';
import * as vscode from 'vscode';
import { TYPES, VSCODE_TYPES } from '../../di.types';
import { kill } from '../../utils/process';
import { OutputChannel } from '../../vscode/output/output.channel';

const START_UP_COMPLETE_MSG = 'Javalin started in';
Expand Down Expand Up @@ -162,17 +162,9 @@ export class ModelServerLauncher implements vscode.Disposable {
/**
* Stops the server.
*/
stop(): void {
async stop(): Promise<void> {
if (this.serverProcess && this.serverProcess.pid && !this.serverProcess.killed) {
kill(this.serverProcess.pid, 'SIGINT', error => console.error('Error', error));

if (!this.serverProcess.killed) {
this.serverProcess.kill('SIGINT');
}
await kill(this.serverProcess.pid, 'SIGINT');
}
}

dispose(): void {
this.stop();
}
}
132 changes: 132 additions & 0 deletions client/packages/uml-vscode-integration/extension/src/utils/process.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/********************************************************************************
* Copyright (c) 2023 EclipseSource 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 WITH Classpath-exception-2.0
********************************************************************************/

// Modified version of the tree-kill package: https://github.com/pkrumins/node-tree-kill

import * as childProcess from 'child_process';

export async function kill(pid: number, signal: string): Promise<void> {
const tree: any = {};
const pidsToProcess: any = {};
tree[pid] = [];
pidsToProcess[pid] = 1;

let resolve: ((value: void) => void) | undefined = undefined;

const promise = new Promise<void>(res => {
resolve = res;
});

switch (process.platform) {
case 'win32':
childProcess.execSync(`taskkill /F /T /PID ${pid}`);
resolve!();
break;
case 'darwin':
buildProcessTree(
pid,
tree,
pidsToProcess,
(parentPid: any) => childProcess.spawn('pgrep', ['-P', parentPid]),
() => {
killAll(tree, signal);
resolve!();
}
);
break;
// case 'sunos':
// buildProcessTreeSunOS(pid, tree, pidsToProcess, function () {
// killAll(tree, signal, callback);
// });
// break;
default: // Linux
buildProcessTree(
pid,
tree,
pidsToProcess,
(parentPid: string) => childProcess.spawn('ps', ['-o', 'pid', '--no-headers', '--ppid', parentPid]),
() => {
killAll(tree, signal);
resolve!();
}
);
break;
}

return promise;
}

function killAll(tree: any, signal: any): void {
const killed: any = {};
// eslint-disable-next-line no-useless-catch
try {
Object.keys(tree).forEach(pid => {
tree[pid].forEach((pidpid: any) => {
if (!killed[pidpid]) {
killPid(pidpid, signal);
killed[pidpid] = 1;
}
});
if (!killed[pid]) {
killPid(pid, signal);
killed[pid] = 1;
}
});
} catch (err) {
throw err;
}
}

function killPid(pid: any, signal: any): void {
try {
process.kill(parseInt(pid, 10), signal);
} catch (err: any) {
if (err.code !== 'ESRCH') {
throw err;
}
}
}

function buildProcessTree(parentPid: any, tree: any, pidsToProcess: any, spawnChildProcessesList: any, cb: any): void {
const ps = spawnChildProcessesList(parentPid);
let allData: any = '';
ps.stdout.on('data', (data: any) => {
data = data.toString('ascii');
allData += data;
});

const onClose = (code: any): void => {
delete pidsToProcess[parentPid];

if (code !== 0) {
// no more parent processes
if (Object.keys(pidsToProcess).length === 0) {
cb();
}
return;
}

allData.match(/\d+/g).forEach((pid: any) => {
pid = parseInt(pid, 10);
tree[parentPid].push(pid);
tree[pid] = [];
pidsToProcess[pid] = 1;
buildProcessTree(pid, tree, pidsToProcess, spawnChildProcessesList, cb);
});
};

ps.on('close', onClose);
}
13 changes: 4 additions & 9 deletions client/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3079,10 +3079,10 @@
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-7.0.5.tgz#b1d2f772142a301538fae9bdf9cf15b9f2573a29"
integrity sha512-hKB88y3YHL8oPOs/CNlaXtjWn93+Bs48sDQR37ZUqG2tLeCS7EA1cmnkKsuQsub9OKEB/y/Rw9zqJqqNSbqVlQ==

"@types/vscode@^1.54.0":
version "1.75.1"
resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.75.1.tgz#21d16480c04a50a1ceb693ea7577c58f88301579"
integrity sha512-emg7wdsTFzdi+elvoyoA+Q8keEautdQHyY5LNmHVM4PTpY8JgOTVADrGVyXGepJ6dVW2OS5/xnLUWh+nZxvdiA==
"@types/vscode@^1.63.0":
version "1.77.0"
resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.77.0.tgz#f92f15a636abc9ef562f44dd8af6766aefedb445"
integrity sha512-MWFN5R7a33n8eJZJmdVlifjig3LWUNRrPeO1xemIcZ0ae0TEQuRc7G2xV0LUX78RZFECY1plYBn+dP/Acc3L0Q==

"@types/write-json-file@^2.2.1":
version "2.2.1"
Expand Down Expand Up @@ -11272,11 +11272,6 @@ trash@^7.2.0:
resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9"
integrity sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==

tree-kill@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==

treeverse@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/treeverse/-/treeverse-2.0.0.tgz#036dcef04bc3fd79a9b79a68d4da03e882d8a9ca"
Expand Down

0 comments on commit 05f99fa

Please sign in to comment.