1
- /// <reference path="../../definitions/node.d.ts"/>
1
+ import { EventEmitter } from 'events' ;
2
+ import { ChildProcess , spawn } from 'child_process' ;
2
3
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' ;
8
5
9
6
function debug ( message : string ) : void {
10
7
if ( process . env [ 'TASK_TEST_TRACE' ] ) {
11
8
console . log ( message ) ;
12
9
}
13
10
}
14
11
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 {
16
27
constructor ( ) {
17
28
super ( ) ;
18
29
}
19
30
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
+
23
35
public stderr : string ;
24
36
public stdout : string ;
25
37
26
38
public ensureKill ( ) : void {
27
- if ( this . _childProcess ) {
28
- this . _childProcess . kill ( ) ;
39
+ if ( this . childProcess ) {
40
+ this . childProcess . kill ( ) ;
29
41
}
30
-
31
- this . _childProcess = undefined ;
32
42
}
33
43
34
- public run ( psPath : string , done ) {
44
+ public run ( psPath : string , done : ( err ?: any ) => void ) : void {
35
45
this . ensureStarted ( ) ;
36
46
this . runPromise ( psPath )
37
- . then ( ( ) => {
38
- done ( ) ;
39
- } )
40
- . catch ( ( err ) => {
41
- done ( err ) ;
42
- } ) ;
47
+ . then ( ( ) => done ( ) )
48
+ . catch ( ( err ) => done ( err ) ) ;
43
49
}
44
50
45
51
private ensureStarted ( ) : void {
46
- if ( this . _childProcess ) {
52
+ if ( this . childProcess ) {
47
53
return ;
48
54
}
49
55
56
+ const powershell = shell . which ( 'powershell.exe' ) ?. stdout ;
57
+ if ( ! powershell ) {
58
+ throw new Error ( 'powershell.exe not found' ) ;
59
+ }
60
+
50
61
this . emit ( 'starting' ) ;
51
- var powershell = shell . which ( 'powershell.exe' ) . stdout ;
52
- this . _childProcess = child . spawn (
62
+ this . childProcess = spawn (
53
63
powershell , // command
54
64
[ // args
55
65
'-NoLogo' ,
@@ -65,51 +75,55 @@ class PSEngineRunner extends events.EventEmitter {
65
75
cwd : __dirname ,
66
76
env : process . env
67
77
} ) ;
68
- this . _childProcess . stdout . on (
78
+ this . childProcess . stdout . on (
69
79
'data' ,
70
80
( data ) => {
71
81
// Check for special ouput indicating end of test.
72
82
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' ) ) ;
75
85
} else {
76
- this . _runDeferred = Promise . resolve ( ) ;
86
+ this . dp . resolve ( ) ;
77
87
}
78
88
} else if ( data != '\n' ) {
79
89
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 / ) ) {
80
90
// The VstsTaskSdk converts error records to error issue commands.
81
91
debug ( 'stdout: ' + data ) ;
82
- this . _errors . push ( data ) ;
92
+ this . errors . push ( data ) ;
83
93
} else {
84
94
// Otherwise, normal stdout.
85
95
debug ( 'stdout: ' + data ) ;
86
96
}
87
97
}
88
98
} ) ;
89
- this . _childProcess . stderr . on (
99
+ this . childProcess . stderr . on (
90
100
'data' ,
91
101
( data ) => {
92
102
// Stderr indicates an error record was written to PowerShell's error pipeline.
93
103
debug ( 'stderr: ' + data ) ;
94
- this . _errors . push ( data ) ;
104
+ this . errors . push ( data ) ;
95
105
} ) ;
96
106
}
97
107
98
108
private runPromise ( psPath : string ) : Promise < void > {
99
109
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 ;
104
116
}
105
117
}
106
118
107
- let _engineRunner : PSEngineRunner = new PSEngineRunner ( ) ;
119
+ const engineRunner : PSEngineRunner = new PSEngineRunner ( ) ;
108
120
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 ) ;
111
123
}
112
124
113
125
export function ensureStopped ( ) : void {
114
- _engineRunner . ensureKill ( ) ;
126
+ engineRunner . ensureKill ( ) ;
115
127
}
128
+
129
+ export default { run, ensureStopped } ;
0 commit comments