1- /// <reference path="../../definitions/node.d.ts"/>
1+ import { EventEmitter } from 'events' ;
2+ import { ChildProcess , spawn } from 'child_process' ;
23
3- import events = require( 'events' ) ;
4- import fs = require( 'fs' ) ;
5- import path = require( 'path' ) ;
6- import child = require( 'child_process' ) ;
7- let shell = require ( 'shelljs' ) ;
4+ import shell from 'shelljs' ;
85
96function debug ( message : string ) : void {
107 if ( process . env [ 'TASK_TEST_TRACE' ] ) {
118 console . log ( message ) ;
129 }
1310}
1411
15- class PSEngineRunner extends events . EventEmitter {
12+ // Thanks to https://stackoverflow.com/a/34637436
13+ class DeferredPromise {
14+ public promise : Promise < void >
15+ public resolve : ( ) => void
16+ public reject : ( reason : any ) => void
17+
18+ constructor ( ) {
19+ this . promise = new Promise ( ( resolve , reject ) => {
20+ this . reject = reject
21+ this . resolve = resolve
22+ } )
23+ }
24+ }
25+
26+ class PSEngineRunner extends EventEmitter {
1627 constructor ( ) {
1728 super ( ) ;
1829 }
1930
20- private _childProcess : child . ChildProcess ;
21- private _errors : string [ ] ;
22- private _runDeferred : Promise < void > ;
31+ private childProcess : ChildProcess ;
32+ private errors : string [ ] ;
33+ private dp : DeferredPromise ;
34+
2335 public stderr : string ;
2436 public stdout : string ;
2537
2638 public ensureKill ( ) : void {
27- if ( this . _childProcess ) {
28- this . _childProcess . kill ( ) ;
39+ if ( this . childProcess ) {
40+ this . childProcess . kill ( ) ;
2941 }
30-
31- this . _childProcess = undefined ;
3242 }
3343
34- public run ( psPath : string , done ) {
44+ public run ( psPath : string , done : ( err ?: any ) => void ) : void {
3545 this . ensureStarted ( ) ;
3646 this . runPromise ( psPath )
37- . then ( ( ) => {
38- done ( ) ;
39- } )
40- . catch ( ( err ) => {
41- done ( err ) ;
42- } ) ;
47+ . then ( ( ) => done ( ) )
48+ . catch ( ( err ) => done ( err ) ) ;
4349 }
4450
4551 private ensureStarted ( ) : void {
46- if ( this . _childProcess ) {
52+ if ( this . childProcess ) {
4753 return ;
4854 }
4955
56+ const powershell = shell . which ( 'powershell.exe' ) ?. stdout ;
57+ if ( ! powershell ) {
58+ throw new Error ( 'powershell.exe not found' ) ;
59+ }
60+
5061 this . emit ( 'starting' ) ;
51- var powershell = shell . which ( 'powershell.exe' ) . stdout ;
52- this . _childProcess = child . spawn (
62+ this . childProcess = spawn (
5363 powershell , // command
5464 [ // args
5565 '-NoLogo' ,
@@ -65,51 +75,55 @@ class PSEngineRunner extends events.EventEmitter {
6575 cwd : __dirname ,
6676 env : process . env
6777 } ) ;
68- this . _childProcess . stdout . on (
78+ this . childProcess . stdout . on (
6979 'data' ,
7080 ( data ) => {
7181 // Check for special ouput indicating end of test.
7282 if ( ( '' + data ) . indexOf ( '_END_OF_TEST_ce10a77a_' ) >= 0 ) {
73- if ( this . _errors . length > 0 ) {
74- this . _runDeferred = Promise . reject ( this . _errors . join ( '\n' ) ) ;
83+ if ( this . errors . length > 0 ) {
84+ this . dp . reject ( this . errors . join ( '\n' ) ) ;
7585 } else {
76- this . _runDeferred = Promise . resolve ( ) ;
86+ this . dp . resolve ( ) ;
7787 }
7888 } else if ( data != '\n' ) {
7989 if ( ( '' + data ) . match ( / # # v s o \[ t a s k .l o g i s s u e .* t y p e = e r r o r / ) ) {
8090 // The VstsTaskSdk converts error records to error issue commands.
8191 debug ( 'stdout: ' + data ) ;
82- this . _errors . push ( data ) ;
92+ this . errors . push ( data ) ;
8393 } else {
8494 // Otherwise, normal stdout.
8595 debug ( 'stdout: ' + data ) ;
8696 }
8797 }
8898 } ) ;
89- this . _childProcess . stderr . on (
99+ this . childProcess . stderr . on (
90100 'data' ,
91101 ( data ) => {
92102 // Stderr indicates an error record was written to PowerShell's error pipeline.
93103 debug ( 'stderr: ' + data ) ;
94- this . _errors . push ( data ) ;
104+ this . errors . push ( data ) ;
95105 } ) ;
96106 }
97107
98108 private runPromise ( psPath : string ) : Promise < void > {
99109 this . emit ( 'running test' ) ;
100- this . _errors = [ ] ;
101- this . _runDeferred = Promise . resolve ( ) ;
102- this . _childProcess . stdin . write ( psPath + '\n' )
103- return this . _runDeferred ;
110+
111+ this . errors = [ ] ;
112+ this . dp = new DeferredPromise ( ) ;
113+ this . childProcess . stdin . write ( psPath + '\n' )
114+
115+ return this . dp . promise ;
104116 }
105117}
106118
107- let _engineRunner : PSEngineRunner = new PSEngineRunner ( ) ;
119+ const engineRunner : PSEngineRunner = new PSEngineRunner ( ) ;
108120
109- export function run ( psPath : string , done ) : void {
110- _engineRunner . run ( psPath , done ) ;
121+ export function run ( psPath : string , done : ( err ?: any ) => void ) : void {
122+ engineRunner . run ( psPath , done ) ;
111123}
112124
113125export function ensureStopped ( ) : void {
114- _engineRunner . ensureKill ( ) ;
126+ engineRunner . ensureKill ( ) ;
115127}
128+
129+ export default { run, ensureStopped } ;
0 commit comments