@theia/process 1.45.1 → 1.46.0-next.72

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.
Files changed (69) hide show
  1. package/README.md +30 -30
  2. package/lib/common/process-common-module.d.ts +3 -3
  3. package/lib/common/process-common-module.js +22 -22
  4. package/lib/common/process-manager-types.d.ts +35 -35
  5. package/lib/common/process-manager-types.js +23 -23
  6. package/lib/common/shell-command-builder.d.ts +49 -49
  7. package/lib/common/shell-command-builder.js +174 -174
  8. package/lib/common/shell-command-builder.slow-spec.d.ts +9 -9
  9. package/lib/common/shell-command-builder.slow-spec.js +404 -404
  10. package/lib/common/shell-quoting.d.ts +91 -91
  11. package/lib/common/shell-quoting.js +145 -145
  12. package/lib/common/shell-quoting.spec.d.ts +1 -1
  13. package/lib/common/shell-quoting.spec.js +170 -170
  14. package/lib/node/dev-null-stream.d.ts +17 -17
  15. package/lib/node/dev-null-stream.js +41 -41
  16. package/lib/node/index.d.ts +6 -6
  17. package/lib/node/index.js +33 -33
  18. package/lib/node/multi-ring-buffer.d.ts +68 -68
  19. package/lib/node/multi-ring-buffer.js +310 -310
  20. package/lib/node/multi-ring-buffer.spec.d.ts +1 -1
  21. package/lib/node/multi-ring-buffer.spec.js +422 -422
  22. package/lib/node/process-backend-module.d.ts +3 -3
  23. package/lib/node/process-backend-module.js +56 -56
  24. package/lib/node/process-manager.d.ts +33 -33
  25. package/lib/node/process-manager.js +113 -113
  26. package/lib/node/process.d.ts +95 -95
  27. package/lib/node/process.js +153 -153
  28. package/lib/node/pseudo-pty.d.ts +22 -22
  29. package/lib/node/pseudo-pty.js +38 -38
  30. package/lib/node/raw-process.d.ts +45 -45
  31. package/lib/node/raw-process.js +115 -115
  32. package/lib/node/raw-process.spec.d.ts +1 -1
  33. package/lib/node/raw-process.spec.js +164 -164
  34. package/lib/node/task-terminal-process.d.ts +10 -10
  35. package/lib/node/task-terminal-process.js +47 -47
  36. package/lib/node/terminal-process.d.ts +60 -60
  37. package/lib/node/terminal-process.js +259 -259
  38. package/lib/node/terminal-process.spec.d.ts +1 -1
  39. package/lib/node/terminal-process.spec.js +103 -103
  40. package/lib/node/test/process-test-container.d.ts +2 -2
  41. package/lib/node/test/process-test-container.js +28 -28
  42. package/lib/node/utils.d.ts +16 -16
  43. package/lib/node/utils.js +77 -77
  44. package/package.json +4 -4
  45. package/src/common/process-common-module.ts +22 -22
  46. package/src/common/process-manager-types.ts +58 -58
  47. package/src/common/shell-command-builder.slow-spec.ts +486 -486
  48. package/src/common/shell-command-builder.ts +187 -187
  49. package/src/common/shell-quoting.spec.ts +176 -176
  50. package/src/common/shell-quoting.ts +236 -236
  51. package/src/common/tests/$weird(),file=name.js +1 -1
  52. package/src/common/tests/white space.js +1 -1
  53. package/src/node/dev-null-stream.ts +47 -47
  54. package/src/node/index.ts +22 -22
  55. package/src/node/multi-ring-buffer.spec.ts +486 -486
  56. package/src/node/multi-ring-buffer.ts +348 -348
  57. package/src/node/process-backend-module.ts +67 -67
  58. package/src/node/process-manager.ts +107 -107
  59. package/src/node/process.ts +207 -207
  60. package/src/node/pseudo-pty.ts +54 -54
  61. package/src/node/raw-process.spec.ts +199 -199
  62. package/src/node/raw-process.ts +156 -156
  63. package/src/node/string-argv.d.ts +21 -21
  64. package/src/node/task-terminal-process.ts +41 -41
  65. package/src/node/terminal-process.spec.ts +121 -121
  66. package/src/node/terminal-process.ts +290 -290
  67. package/src/node/test/process-fork-test.js +22 -22
  68. package/src/node/test/process-test-container.ts +27 -27
  69. package/src/node/utils.ts +79 -79
@@ -1,116 +1,116 @@
1
- "use strict";
2
- // *****************************************************************************
3
- // Copyright (C) 2017 Ericsson and others.
4
- //
5
- // This program and the accompanying materials are made available under the
6
- // terms of the Eclipse Public License v. 2.0 which is available at
7
- // http://www.eclipse.org/legal/epl-2.0.
8
- //
9
- // This Source Code may also be made available under the following Secondary
10
- // Licenses when the conditions for such availability set forth in the Eclipse
11
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
- // with the GNU Classpath Exception which is available at
13
- // https://www.gnu.org/software/classpath/license.html.
14
- //
15
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
- // *****************************************************************************
17
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
18
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
19
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
20
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
21
- return c > 3 && r && Object.defineProperty(target, key, r), r;
22
- };
23
- var __metadata = (this && this.__metadata) || function (k, v) {
24
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
25
- };
26
- var __param = (this && this.__param) || function (paramIndex, decorator) {
27
- return function (target, key) { decorator(target, key, paramIndex); }
28
- };
29
- Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.RawProcess = exports.RawProcessFactory = exports.RawProcessOptions = exports.DevNullStream = void 0;
31
- const inversify_1 = require("@theia/core/shared/inversify");
32
- const process_manager_1 = require("./process-manager");
33
- const common_1 = require("@theia/core/lib/common");
34
- const process_1 = require("./process");
35
- const child_process_1 = require("child_process");
36
- // The class was here before, exporting to not break anything.
37
- var dev_null_stream_1 = require("./dev-null-stream");
38
- Object.defineProperty(exports, "DevNullStream", { enumerable: true, get: function () { return dev_null_stream_1.DevNullStream; } });
39
- const dev_null_stream_2 = require("./dev-null-stream");
40
- exports.RawProcessOptions = Symbol('RawProcessOptions');
41
- exports.RawProcessFactory = Symbol('RawProcessFactory');
42
- let RawProcess = class RawProcess extends process_1.Process {
43
- constructor(// eslint-disable-next-line @typescript-eslint/indent
44
- options, processManager, logger) {
45
- super(processManager, logger, process_1.ProcessType.Raw, options);
46
- const executable = this.isForkOptions(options) ? options.modulePath : options.command;
47
- this.logger.debug(`Starting raw process: ${executable},`
48
- + ` with args: ${options.args ? options.args.join(' ') : ''}, `
49
- + ` with options: ${JSON.stringify(options.options)}`);
50
- // About catching errors: spawn will sometimes throw directly
51
- // (EACCES on Linux), sometimes return a Process object with the pid
52
- // property undefined (ENOENT on Linux) and then emit an 'error' event.
53
- // For now, we try to normalize that into always emitting an 'error'
54
- // event.
55
- try {
56
- if (this.isForkOptions(options)) {
57
- this.process = (0, child_process_1.fork)(options.modulePath, options.args || [], options.options || {});
58
- }
59
- else {
60
- this.process = (0, child_process_1.spawn)(options.command, options.args || [], options.options || {});
61
- }
62
- this.process.on('error', (error) => {
63
- error.code = error.code || 'Unknown error';
64
- this.emitOnError(error);
65
- });
66
- // When no stdio option is passed, it is null by default.
67
- this.outputStream = this.process.stdout || new dev_null_stream_2.DevNullStream({ autoDestroy: true });
68
- this.inputStream = this.process.stdin || new dev_null_stream_2.DevNullStream({ autoDestroy: true });
69
- this.errorStream = this.process.stderr || new dev_null_stream_2.DevNullStream({ autoDestroy: true });
70
- this.process.on('exit', (exitCode, signal) => {
71
- // node's child_process exit sets the unused parameter to null,
72
- // but we want it to be undefined instead.
73
- this.emitOnExit(typeof exitCode === 'number' ? exitCode : undefined, typeof signal === 'string' ? signal : undefined);
74
- this.processManager.unregister(this);
75
- });
76
- this.process.on('close', (exitCode, signal) => {
77
- // node's child_process exit sets the unused parameter to null,
78
- // but we want it to be undefined instead.
79
- this.emitOnClose(typeof exitCode === 'number' ? exitCode : undefined, typeof signal === 'string' ? signal : undefined);
80
- });
81
- if (this.process.pid !== undefined) {
82
- process.nextTick(this.emitOnStarted.bind(this));
83
- }
84
- }
85
- catch (error) {
86
- /* When an error is thrown, set up some fake streams, so the client
87
- code doesn't break because these field are undefined. */
88
- this.outputStream = new dev_null_stream_2.DevNullStream({ autoDestroy: true });
89
- this.inputStream = new dev_null_stream_2.DevNullStream({ autoDestroy: true });
90
- this.errorStream = new dev_null_stream_2.DevNullStream({ autoDestroy: true });
91
- /* Call the client error handler, but first give them a chance to register it. */
92
- this.emitOnErrorAsync(error);
93
- }
94
- }
95
- get pid() {
96
- if (!this.process || !this.process.pid) {
97
- throw new Error('process did not start correctly');
98
- }
99
- return this.process.pid;
100
- }
101
- kill(signal) {
102
- if (this.process && this.killed === false) {
103
- this.process.kill(signal);
104
- }
105
- }
106
- };
107
- RawProcess = __decorate([
108
- (0, inversify_1.injectable)(),
109
- __param(0, (0, inversify_1.inject)(exports.RawProcessOptions)),
110
- __param(1, (0, inversify_1.inject)(process_manager_1.ProcessManager)),
111
- __param(2, (0, inversify_1.inject)(common_1.ILogger)),
112
- __param(2, (0, inversify_1.named)('process')),
113
- __metadata("design:paramtypes", [Object, process_manager_1.ProcessManager, Object])
114
- ], RawProcess);
115
- exports.RawProcess = RawProcess;
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2017 Ericsson and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
18
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
19
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
20
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
21
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
22
+ };
23
+ var __metadata = (this && this.__metadata) || function (k, v) {
24
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
25
+ };
26
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
27
+ return function (target, key) { decorator(target, key, paramIndex); }
28
+ };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.RawProcess = exports.RawProcessFactory = exports.RawProcessOptions = exports.DevNullStream = void 0;
31
+ const inversify_1 = require("@theia/core/shared/inversify");
32
+ const process_manager_1 = require("./process-manager");
33
+ const common_1 = require("@theia/core/lib/common");
34
+ const process_1 = require("./process");
35
+ const child_process_1 = require("child_process");
36
+ // The class was here before, exporting to not break anything.
37
+ var dev_null_stream_1 = require("./dev-null-stream");
38
+ Object.defineProperty(exports, "DevNullStream", { enumerable: true, get: function () { return dev_null_stream_1.DevNullStream; } });
39
+ const dev_null_stream_2 = require("./dev-null-stream");
40
+ exports.RawProcessOptions = Symbol('RawProcessOptions');
41
+ exports.RawProcessFactory = Symbol('RawProcessFactory');
42
+ let RawProcess = class RawProcess extends process_1.Process {
43
+ constructor(// eslint-disable-next-line @typescript-eslint/indent
44
+ options, processManager, logger) {
45
+ super(processManager, logger, process_1.ProcessType.Raw, options);
46
+ const executable = this.isForkOptions(options) ? options.modulePath : options.command;
47
+ this.logger.debug(`Starting raw process: ${executable},`
48
+ + ` with args: ${options.args ? options.args.join(' ') : ''}, `
49
+ + ` with options: ${JSON.stringify(options.options)}`);
50
+ // About catching errors: spawn will sometimes throw directly
51
+ // (EACCES on Linux), sometimes return a Process object with the pid
52
+ // property undefined (ENOENT on Linux) and then emit an 'error' event.
53
+ // For now, we try to normalize that into always emitting an 'error'
54
+ // event.
55
+ try {
56
+ if (this.isForkOptions(options)) {
57
+ this.process = (0, child_process_1.fork)(options.modulePath, options.args || [], options.options || {});
58
+ }
59
+ else {
60
+ this.process = (0, child_process_1.spawn)(options.command, options.args || [], options.options || {});
61
+ }
62
+ this.process.on('error', (error) => {
63
+ error.code = error.code || 'Unknown error';
64
+ this.emitOnError(error);
65
+ });
66
+ // When no stdio option is passed, it is null by default.
67
+ this.outputStream = this.process.stdout || new dev_null_stream_2.DevNullStream({ autoDestroy: true });
68
+ this.inputStream = this.process.stdin || new dev_null_stream_2.DevNullStream({ autoDestroy: true });
69
+ this.errorStream = this.process.stderr || new dev_null_stream_2.DevNullStream({ autoDestroy: true });
70
+ this.process.on('exit', (exitCode, signal) => {
71
+ // node's child_process exit sets the unused parameter to null,
72
+ // but we want it to be undefined instead.
73
+ this.emitOnExit(typeof exitCode === 'number' ? exitCode : undefined, typeof signal === 'string' ? signal : undefined);
74
+ this.processManager.unregister(this);
75
+ });
76
+ this.process.on('close', (exitCode, signal) => {
77
+ // node's child_process exit sets the unused parameter to null,
78
+ // but we want it to be undefined instead.
79
+ this.emitOnClose(typeof exitCode === 'number' ? exitCode : undefined, typeof signal === 'string' ? signal : undefined);
80
+ });
81
+ if (this.process.pid !== undefined) {
82
+ process.nextTick(this.emitOnStarted.bind(this));
83
+ }
84
+ }
85
+ catch (error) {
86
+ /* When an error is thrown, set up some fake streams, so the client
87
+ code doesn't break because these field are undefined. */
88
+ this.outputStream = new dev_null_stream_2.DevNullStream({ autoDestroy: true });
89
+ this.inputStream = new dev_null_stream_2.DevNullStream({ autoDestroy: true });
90
+ this.errorStream = new dev_null_stream_2.DevNullStream({ autoDestroy: true });
91
+ /* Call the client error handler, but first give them a chance to register it. */
92
+ this.emitOnErrorAsync(error);
93
+ }
94
+ }
95
+ get pid() {
96
+ if (!this.process || !this.process.pid) {
97
+ throw new Error('process did not start correctly');
98
+ }
99
+ return this.process.pid;
100
+ }
101
+ kill(signal) {
102
+ if (this.process && this.killed === false) {
103
+ this.process.kill(signal);
104
+ }
105
+ }
106
+ };
107
+ RawProcess = __decorate([
108
+ (0, inversify_1.injectable)(),
109
+ __param(0, (0, inversify_1.inject)(exports.RawProcessOptions)),
110
+ __param(1, (0, inversify_1.inject)(process_manager_1.ProcessManager)),
111
+ __param(2, (0, inversify_1.inject)(common_1.ILogger)),
112
+ __param(2, (0, inversify_1.named)('process')),
113
+ __metadata("design:paramtypes", [Object, process_manager_1.ProcessManager, Object])
114
+ ], RawProcess);
115
+ exports.RawProcess = RawProcess;
116
116
  //# sourceMappingURL=raw-process.js.map
@@ -1,2 +1,2 @@
1
- export {};
1
+ export {};
2
2
  //# sourceMappingURL=raw-process.spec.d.ts.map
@@ -1,165 +1,165 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- // *****************************************************************************
4
- // Copyright (C) 2017 Ericsson and others.
5
- //
6
- // This program and the accompanying materials are made available under the
7
- // terms of the Eclipse Public License v. 2.0 which is available at
8
- // http://www.eclipse.org/legal/epl-2.0.
9
- //
10
- // This Source Code may also be made available under the following Secondary
11
- // Licenses when the conditions for such availability set forth in the Eclipse
12
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
13
- // with the GNU Classpath Exception which is available at
14
- // https://www.gnu.org/software/classpath/license.html.
15
- //
16
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
17
- // *****************************************************************************
18
- const chai = require("chai");
19
- const process = require("process");
20
- const stream = require("stream");
21
- const process_test_container_1 = require("./test/process-test-container");
22
- const raw_process_1 = require("./raw-process");
23
- const temp = require("temp");
24
- const fs = require("fs");
25
- const path = require("path");
26
- const core_1 = require("@theia/core");
27
- /* Allow to create temporary files, but delete them when we're done. */
28
- const track = temp.track();
29
- /**
30
- * Globals
31
- */
32
- const expect = chai.expect;
33
- const FORK_TEST_FILE = path.join(__dirname, '../../src/node/test/process-fork-test.js');
34
- describe('RawProcess', function () {
35
- this.timeout(20000);
36
- let rawProcessFactory;
37
- beforeEach(() => {
38
- rawProcessFactory = (0, process_test_container_1.createProcessTestContainer)().get(raw_process_1.RawProcessFactory);
39
- });
40
- after(() => {
41
- track.cleanupSync();
42
- });
43
- it('test error on non-existent path', async function () {
44
- const error = await new Promise((resolve, reject) => {
45
- const proc = rawProcessFactory({ command: '/non-existent' });
46
- proc.onStart(reject);
47
- proc.onError(resolve);
48
- proc.onExit(reject);
49
- });
50
- expect(error.code).eq('ENOENT');
51
- });
52
- it('test error on non-executable path', async function () {
53
- // Create a non-executable file.
54
- const f = track.openSync('non-executable');
55
- fs.writeSync(f.fd, 'echo bob');
56
- // Make really sure it's non-executable.
57
- let mode = fs.fstatSync(f.fd).mode;
58
- mode &= ~fs.constants.S_IXUSR;
59
- mode &= ~fs.constants.S_IXGRP;
60
- mode &= ~fs.constants.S_IXOTH;
61
- fs.fchmodSync(f.fd, mode);
62
- fs.closeSync(f.fd);
63
- const error = await new Promise((resolve, reject) => {
64
- const proc = rawProcessFactory({ command: f.path });
65
- proc.onStart(reject);
66
- proc.onError(resolve);
67
- proc.onExit(reject);
68
- });
69
- // On Windows, we get 'UNKNOWN'.
70
- const expectedCode = core_1.isWindows ? 'UNKNOWN' : 'EACCES';
71
- expect(error.code).eq(expectedCode);
72
- });
73
- it('test start event', function () {
74
- return new Promise(async (resolve, reject) => {
75
- const args = ['-e', 'process.exit(3)'];
76
- const rawProcess = rawProcessFactory({ command: process.execPath, 'args': args });
77
- rawProcess.onStart(resolve);
78
- rawProcess.onError(reject);
79
- rawProcess.onExit(reject);
80
- });
81
- });
82
- it('test exit', async function () {
83
- const args = ['--version'];
84
- const rawProcess = rawProcessFactory({ command: process.execPath, 'args': args });
85
- const p = new Promise((resolve, reject) => {
86
- rawProcess.onError(reject);
87
- rawProcess.onExit(event => {
88
- if (event.code === undefined) {
89
- reject(new Error('event.code is undefined'));
90
- }
91
- else {
92
- resolve(event.code);
93
- }
94
- });
95
- });
96
- const exitCode = await p;
97
- expect(exitCode).equal(0);
98
- });
99
- it('test pipe stdout stream', async function () {
100
- const output = await new Promise(async (resolve, reject) => {
101
- const args = ['-e', 'console.log("text to stdout")'];
102
- const outStream = new stream.PassThrough();
103
- const rawProcess = rawProcessFactory({ command: process.execPath, 'args': args });
104
- rawProcess.onError(reject);
105
- rawProcess.outputStream.pipe(outStream);
106
- let buf = '';
107
- outStream.on('data', data => {
108
- buf += data.toString();
109
- });
110
- outStream.on('end', () => {
111
- resolve(buf.trim());
112
- });
113
- });
114
- expect(output).to.be.equal('text to stdout');
115
- });
116
- it('test pipe stderr stream', async function () {
117
- const output = await new Promise(async (resolve, reject) => {
118
- const args = ['-e', 'console.error("text to stderr")'];
119
- const outStream = new stream.PassThrough();
120
- const rawProcess = rawProcessFactory({ command: process.execPath, 'args': args });
121
- rawProcess.onError(reject);
122
- rawProcess.errorStream.pipe(outStream);
123
- let buf = '';
124
- outStream.on('data', data => {
125
- buf += data.toString();
126
- });
127
- outStream.on('end', () => {
128
- resolve(buf.trim());
129
- });
130
- });
131
- expect(output).to.be.equal('text to stderr');
132
- });
133
- it('test forked pipe stdout stream', async function () {
134
- const args = ['version'];
135
- const rawProcess = rawProcessFactory({ modulePath: FORK_TEST_FILE, args, options: { stdio: 'pipe' } });
136
- const outStream = new stream.PassThrough();
137
- const p = new Promise((resolve, reject) => {
138
- let version = '';
139
- outStream.on('data', data => {
140
- version += data.toString();
141
- });
142
- outStream.on('end', () => {
143
- resolve(version.trim());
144
- });
145
- });
146
- rawProcess.outputStream.pipe(outStream);
147
- expect(await p).to.be.equal('1.0.0');
148
- });
149
- it('test forked pipe stderr stream', async function () {
150
- const rawProcess = rawProcessFactory({ modulePath: FORK_TEST_FILE, args: [], options: { stdio: 'pipe' } });
151
- const outStream = new stream.PassThrough();
152
- const p = new Promise((resolve, reject) => {
153
- let version = '';
154
- outStream.on('data', data => {
155
- version += data.toString();
156
- });
157
- outStream.on('end', () => {
158
- resolve(version.trim());
159
- });
160
- });
161
- rawProcess.errorStream.pipe(outStream);
162
- expect(await p).to.have.string('Error');
163
- });
164
- });
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // *****************************************************************************
4
+ // Copyright (C) 2017 Ericsson and others.
5
+ //
6
+ // This program and the accompanying materials are made available under the
7
+ // terms of the Eclipse Public License v. 2.0 which is available at
8
+ // http://www.eclipse.org/legal/epl-2.0.
9
+ //
10
+ // This Source Code may also be made available under the following Secondary
11
+ // Licenses when the conditions for such availability set forth in the Eclipse
12
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
13
+ // with the GNU Classpath Exception which is available at
14
+ // https://www.gnu.org/software/classpath/license.html.
15
+ //
16
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
17
+ // *****************************************************************************
18
+ const chai = require("chai");
19
+ const process = require("process");
20
+ const stream = require("stream");
21
+ const process_test_container_1 = require("./test/process-test-container");
22
+ const raw_process_1 = require("./raw-process");
23
+ const temp = require("temp");
24
+ const fs = require("fs");
25
+ const path = require("path");
26
+ const core_1 = require("@theia/core");
27
+ /* Allow to create temporary files, but delete them when we're done. */
28
+ const track = temp.track();
29
+ /**
30
+ * Globals
31
+ */
32
+ const expect = chai.expect;
33
+ const FORK_TEST_FILE = path.join(__dirname, '../../src/node/test/process-fork-test.js');
34
+ describe('RawProcess', function () {
35
+ this.timeout(20000);
36
+ let rawProcessFactory;
37
+ beforeEach(() => {
38
+ rawProcessFactory = (0, process_test_container_1.createProcessTestContainer)().get(raw_process_1.RawProcessFactory);
39
+ });
40
+ after(() => {
41
+ track.cleanupSync();
42
+ });
43
+ it('test error on non-existent path', async function () {
44
+ const error = await new Promise((resolve, reject) => {
45
+ const proc = rawProcessFactory({ command: '/non-existent' });
46
+ proc.onStart(reject);
47
+ proc.onError(resolve);
48
+ proc.onExit(reject);
49
+ });
50
+ expect(error.code).eq('ENOENT');
51
+ });
52
+ it('test error on non-executable path', async function () {
53
+ // Create a non-executable file.
54
+ const f = track.openSync('non-executable');
55
+ fs.writeSync(f.fd, 'echo bob');
56
+ // Make really sure it's non-executable.
57
+ let mode = fs.fstatSync(f.fd).mode;
58
+ mode &= ~fs.constants.S_IXUSR;
59
+ mode &= ~fs.constants.S_IXGRP;
60
+ mode &= ~fs.constants.S_IXOTH;
61
+ fs.fchmodSync(f.fd, mode);
62
+ fs.closeSync(f.fd);
63
+ const error = await new Promise((resolve, reject) => {
64
+ const proc = rawProcessFactory({ command: f.path });
65
+ proc.onStart(reject);
66
+ proc.onError(resolve);
67
+ proc.onExit(reject);
68
+ });
69
+ // On Windows, we get 'UNKNOWN'.
70
+ const expectedCode = core_1.isWindows ? 'UNKNOWN' : 'EACCES';
71
+ expect(error.code).eq(expectedCode);
72
+ });
73
+ it('test start event', function () {
74
+ return new Promise(async (resolve, reject) => {
75
+ const args = ['-e', 'process.exit(3)'];
76
+ const rawProcess = rawProcessFactory({ command: process.execPath, 'args': args });
77
+ rawProcess.onStart(resolve);
78
+ rawProcess.onError(reject);
79
+ rawProcess.onExit(reject);
80
+ });
81
+ });
82
+ it('test exit', async function () {
83
+ const args = ['--version'];
84
+ const rawProcess = rawProcessFactory({ command: process.execPath, 'args': args });
85
+ const p = new Promise((resolve, reject) => {
86
+ rawProcess.onError(reject);
87
+ rawProcess.onExit(event => {
88
+ if (event.code === undefined) {
89
+ reject(new Error('event.code is undefined'));
90
+ }
91
+ else {
92
+ resolve(event.code);
93
+ }
94
+ });
95
+ });
96
+ const exitCode = await p;
97
+ expect(exitCode).equal(0);
98
+ });
99
+ it('test pipe stdout stream', async function () {
100
+ const output = await new Promise(async (resolve, reject) => {
101
+ const args = ['-e', 'console.log("text to stdout")'];
102
+ const outStream = new stream.PassThrough();
103
+ const rawProcess = rawProcessFactory({ command: process.execPath, 'args': args });
104
+ rawProcess.onError(reject);
105
+ rawProcess.outputStream.pipe(outStream);
106
+ let buf = '';
107
+ outStream.on('data', data => {
108
+ buf += data.toString();
109
+ });
110
+ outStream.on('end', () => {
111
+ resolve(buf.trim());
112
+ });
113
+ });
114
+ expect(output).to.be.equal('text to stdout');
115
+ });
116
+ it('test pipe stderr stream', async function () {
117
+ const output = await new Promise(async (resolve, reject) => {
118
+ const args = ['-e', 'console.error("text to stderr")'];
119
+ const outStream = new stream.PassThrough();
120
+ const rawProcess = rawProcessFactory({ command: process.execPath, 'args': args });
121
+ rawProcess.onError(reject);
122
+ rawProcess.errorStream.pipe(outStream);
123
+ let buf = '';
124
+ outStream.on('data', data => {
125
+ buf += data.toString();
126
+ });
127
+ outStream.on('end', () => {
128
+ resolve(buf.trim());
129
+ });
130
+ });
131
+ expect(output).to.be.equal('text to stderr');
132
+ });
133
+ it('test forked pipe stdout stream', async function () {
134
+ const args = ['version'];
135
+ const rawProcess = rawProcessFactory({ modulePath: FORK_TEST_FILE, args, options: { stdio: 'pipe' } });
136
+ const outStream = new stream.PassThrough();
137
+ const p = new Promise((resolve, reject) => {
138
+ let version = '';
139
+ outStream.on('data', data => {
140
+ version += data.toString();
141
+ });
142
+ outStream.on('end', () => {
143
+ resolve(version.trim());
144
+ });
145
+ });
146
+ rawProcess.outputStream.pipe(outStream);
147
+ expect(await p).to.be.equal('1.0.0');
148
+ });
149
+ it('test forked pipe stderr stream', async function () {
150
+ const rawProcess = rawProcessFactory({ modulePath: FORK_TEST_FILE, args: [], options: { stdio: 'pipe' } });
151
+ const outStream = new stream.PassThrough();
152
+ const p = new Promise((resolve, reject) => {
153
+ let version = '';
154
+ outStream.on('data', data => {
155
+ version += data.toString();
156
+ });
157
+ outStream.on('end', () => {
158
+ resolve(version.trim());
159
+ });
160
+ });
161
+ rawProcess.errorStream.pipe(outStream);
162
+ expect(await p).to.have.string('Error');
163
+ });
164
+ });
165
165
  //# sourceMappingURL=raw-process.spec.js.map
@@ -1,11 +1,11 @@
1
- import { TerminalProcess, TerminalProcessOptions } from './terminal-process';
2
- export declare const TaskTerminalProcessFactory: unique symbol;
3
- export interface TaskTerminalProcessFactory {
4
- (options: TerminalProcessOptions): TaskTerminalProcess;
5
- }
6
- export declare class TaskTerminalProcess extends TerminalProcess {
7
- exited: boolean;
8
- attachmentAttempted: boolean;
9
- protected onTerminalExit(code: number | undefined, signal: string | undefined): void;
10
- }
1
+ import { TerminalProcess, TerminalProcessOptions } from './terminal-process';
2
+ export declare const TaskTerminalProcessFactory: unique symbol;
3
+ export interface TaskTerminalProcessFactory {
4
+ (options: TerminalProcessOptions): TaskTerminalProcess;
5
+ }
6
+ export declare class TaskTerminalProcess extends TerminalProcess {
7
+ exited: boolean;
8
+ attachmentAttempted: boolean;
9
+ protected onTerminalExit(code: number | undefined, signal: string | undefined): void;
10
+ }
11
11
  //# sourceMappingURL=task-terminal-process.d.ts.map