|
1 | | - |
2 | 1 | import Q = require('q'); |
3 | 2 | import os = require('os'); |
4 | 3 | import events = require('events'); |
@@ -162,6 +161,113 @@ export class ToolRunner extends events.EventEmitter { |
162 | 161 | // Exec - use for long running tools where you need to stream live output as it runs |
163 | 162 | // returns a promise with return code. |
164 | 163 | // |
| 164 | + public execAsync(options?: IExecOptions): Promise<number> { |
| 165 | + this._debug('exec tool: ' + this.toolPath); |
| 166 | + this._debug('Arguments:'); |
| 167 | + this.args.forEach((arg) => { |
| 168 | + this._debug(' ' + arg); |
| 169 | + }); |
| 170 | + |
| 171 | + var success = true; |
| 172 | + options = options || <IExecOptions>{}; |
| 173 | + |
| 174 | + var ops: IExecOptions = { |
| 175 | + cwd: options.cwd || process.cwd(), |
| 176 | + env: options.env || process.env, |
| 177 | + silent: options.silent || false, |
| 178 | + outStream: options.outStream || process.stdout, |
| 179 | + errStream: options.errStream || process.stderr, |
| 180 | + failOnStdErr: options.failOnStdErr || false, |
| 181 | + ignoreReturnCode: options.ignoreReturnCode || false, |
| 182 | + windowsVerbatimArguments: options.windowsVerbatimArguments |
| 183 | + }; |
| 184 | + |
| 185 | + var argString = this.args.join(' ') || ''; |
| 186 | + var cmdString = this.toolPath; |
| 187 | + if (argString) { |
| 188 | + cmdString += (' ' + argString); |
| 189 | + } |
| 190 | + |
| 191 | + // Using split/join to replace the temp path |
| 192 | + cmdString = this.ignoreTempPath(cmdString); |
| 193 | + |
| 194 | + if (!ops.silent) { |
| 195 | + if(this.pipeOutputToTool) { |
| 196 | + var pipeToolArgString = this.pipeOutputToTool.args.join(' ') || ''; |
| 197 | + var pipeToolCmdString = this.ignoreTempPath(this.pipeOutputToTool.toolPath); |
| 198 | + if(pipeToolArgString) { |
| 199 | + pipeToolCmdString += (' ' + pipeToolArgString); |
| 200 | + } |
| 201 | + |
| 202 | + cmdString += ' | ' + pipeToolCmdString; |
| 203 | + } |
| 204 | + |
| 205 | + ops.outStream.write('[command]' + cmdString + os.EOL); |
| 206 | + } |
| 207 | + |
| 208 | + // TODO: filter process.env |
| 209 | + var res = mock.getResponse('exec', cmdString, debug); |
| 210 | + if (res.stdout) { |
| 211 | + this.emit('stdout', res.stdout); |
| 212 | + if (!ops.silent) { |
| 213 | + ops.outStream.write(res.stdout + os.EOL); |
| 214 | + } |
| 215 | + const stdLineArray = res.stdout.split(os.EOL); |
| 216 | + for (const line of stdLineArray.slice(0, -1)) { |
| 217 | + this.emit('stdline', line); |
| 218 | + } |
| 219 | + if(stdLineArray.length > 0 && stdLineArray[stdLineArray.length - 1].length > 0) { |
| 220 | + this.emit('stdline', stdLineArray[stdLineArray.length - 1]); |
| 221 | + } |
| 222 | + } |
| 223 | + |
| 224 | + if (res.stderr) { |
| 225 | + this.emit('stderr', res.stderr); |
| 226 | + |
| 227 | + success = !ops.failOnStdErr; |
| 228 | + if (!ops.silent) { |
| 229 | + var s = ops.failOnStdErr ? ops.errStream : ops.outStream; |
| 230 | + s.write(res.stderr + os.EOL); |
| 231 | + } |
| 232 | + const stdErrArray = res.stderr.split(os.EOL); |
| 233 | + for (const line of stdErrArray.slice(0, -1)) { |
| 234 | + this.emit('errline', line); |
| 235 | + } |
| 236 | + if (stdErrArray.length > 0 && stdErrArray[stdErrArray.length - 1].length > 0) { |
| 237 | + this.emit('errline', stdErrArray[stdErrArray.length - 1]); |
| 238 | + } |
| 239 | + } |
| 240 | + |
| 241 | + |
| 242 | + var code = res.code; |
| 243 | + |
| 244 | + if (!ops.silent) { |
| 245 | + ops.outStream.write('rc:' + res.code + os.EOL); |
| 246 | + } |
| 247 | + |
| 248 | + if (code != 0 && !ops.ignoreReturnCode) { |
| 249 | + success = false; |
| 250 | + } |
| 251 | + |
| 252 | + if (!ops.silent) { |
| 253 | + ops.outStream.write('success:' + success + os.EOL); |
| 254 | + } |
| 255 | + |
| 256 | + return new Promise((resolve, reject) => { |
| 257 | + if (success) { |
| 258 | + resolve(code); |
| 259 | + } |
| 260 | + else { |
| 261 | + reject(new Error(this.toolPath + ' failed with return code: ' + code)); |
| 262 | + } |
| 263 | + }); |
| 264 | + } |
| 265 | + |
| 266 | + /** |
| 267 | + * Exec - use for long running tools where you need to stream live output as it runs |
| 268 | + * @deprecated use `execAsync` instead |
| 269 | + * @returns a promise with return code. |
| 270 | + */ |
165 | 271 | public exec(options?: IExecOptions): Q.Promise<number> { |
166 | 272 | var defer = Q.defer<number>(); |
167 | 273 |
|
@@ -270,8 +376,6 @@ export class ToolRunner extends events.EventEmitter { |
270 | 376 | // but also has limits. For example, no live output and limited to max buffer |
271 | 377 | // |
272 | 378 | public execSync(options?: IExecSyncOptions): IExecSyncResult { |
273 | | - var defer = Q.defer(); |
274 | | - |
275 | 379 | this._debug('exec tool: ' + this.toolPath); |
276 | 380 | this._debug('Arguments:'); |
277 | 381 | this.args.forEach((arg) => { |
|
0 commit comments