(file: string, args: string[], options: SpawnOptions = {})
| 154 | }; |
| 155 | } |
| 156 | public exec(file: string, args: string[], options: SpawnOptions = {}): Promise<ExecutionResult<string>> { |
| 157 | const spawnOptions = this.getDefaultOptions(options); |
| 158 | const proc = spawn(file, args, spawnOptions); |
| 159 | const deferred = createDeferred<ExecutionResult<string>>(); |
| 160 | const disposable: IDisposable = { |
| 161 | dispose: () => { |
| 162 | if (!proc.killed && !deferred.completed) { |
| 163 | ProcessService.kill(proc.pid); |
| 164 | } |
| 165 | } |
| 166 | }; |
| 167 | this.processesToKill.add(disposable); |
| 168 | const disposables: IDisposable[] = []; |
| 169 | |
| 170 | const on = (ee: NodeJS.EventEmitter, name: string, fn: Function) => { |
| 171 | ee.on(name, fn as any); |
| 172 | disposables.push({ dispose: () => ee.removeListener(name, fn as any) as any }); |
| 173 | }; |
| 174 | |
| 175 | if (options.token) { |
| 176 | disposables.push(options.token.onCancellationRequested(disposable.dispose)); |
| 177 | } |
| 178 | |
| 179 | const stdoutBuffers: Buffer[] = []; |
| 180 | on(proc.stdout!, 'data', (data: Buffer) => stdoutBuffers.push(data)); |
| 181 | const stderrBuffers: Buffer[] = []; |
| 182 | on(proc.stderr!, 'data', (data: Buffer) => { |
| 183 | if (options.mergeStdOutErr) { |
| 184 | stdoutBuffers.push(data); |
| 185 | stderrBuffers.push(data); |
| 186 | } else { |
| 187 | stderrBuffers.push(data); |
| 188 | } |
| 189 | }); |
| 190 | |
| 191 | proc.once('close', () => { |
| 192 | if (deferred.completed) { |
| 193 | return; |
| 194 | } |
| 195 | const stderr: string | undefined = |
| 196 | stderrBuffers.length === 0 ? undefined : this.decoder.decode(stderrBuffers); |
| 197 | if (stderr && stderr.length > 0 && options.throwOnStdErr) { |
| 198 | deferred.reject(new StdErrError(stderr)); |
| 199 | } else { |
| 200 | const stdout = this.decoder.decode(stdoutBuffers); |
| 201 | deferred.resolve({ stdout, stderr }); |
| 202 | } |
| 203 | disposables.forEach((d) => d.dispose()); |
| 204 | }); |
| 205 | proc.once('error', (ex) => { |
| 206 | deferred.reject(ex); |
| 207 | disposables.forEach((d) => d.dispose()); |
| 208 | }); |
| 209 | |
| 210 | logProcess(file, args, options); |
| 211 | |
| 212 | return deferred.promise; |
| 213 | } |
no test coverage detected