1
1
import { LOGGER_LEVELS } from '@ionic/cli-framework' ;
2
2
import { createProcessEnv , killProcessTree , onBeforeExit } from '@ionic/utils-process' ;
3
3
import { combineStreams } from '@ionic/utils-stream' ;
4
- import { ERROR_COMMAND_NOT_FOUND , Subprocess , SubprocessError , WhichOptions , which } from '@ionic/utils-subprocess' ;
4
+ import { ERROR_COMMAND_NOT_FOUND , Subprocess , SubprocessError , SubprocessOptions , WhichOptions , which } from '@ionic/utils-subprocess' ;
5
5
import { TERMINAL_INFO } from '@ionic/utils-terminal' ;
6
6
import chalk from 'chalk' ;
7
7
import { ChildProcess , SpawnOptions } from 'child_process' ;
@@ -32,13 +32,12 @@ export class Shell implements IShell {
32
32
this . alterPath = options && options . alterPath ? options . alterPath : ( p : string ) => p ;
33
33
}
34
34
35
- async run ( command : string , args : string [ ] , { stream, killOnExit = true , showCommand = true , showError = true , fatalOnNotFound = true , fatalOnError = true , truncateErrorOutput, ...crossSpawnOptions } : IShellRunOptions ) : Promise < void > {
35
+ async run ( command : string , args : readonly string [ ] , { stream, killOnExit = true , showCommand = true , showError = true , fatalOnNotFound = true , fatalOnError = true , truncateErrorOutput, ...crossSpawnOptions } : IShellRunOptions ) : Promise < void > {
36
36
this . prepareSpawnOptions ( crossSpawnOptions ) ;
37
37
38
- const cmdpath = await this . resolveCommandPath ( command , crossSpawnOptions ) ;
39
- const cmd = new Subprocess ( cmdpath , args , crossSpawnOptions ) ;
38
+ const proc = await this . createSubprocess ( command , args , crossSpawnOptions ) ;
40
39
41
- const fullCmd = cmd . bashify ( ) ;
40
+ const fullCmd = proc . bashify ( ) ;
42
41
const truncatedCmd = fullCmd . length > 80 ? fullCmd . substring ( 0 , 80 ) + '...' : fullCmd ;
43
42
44
43
if ( showCommand && this . e . log . level >= LOGGER_LEVELS . INFO ) {
@@ -48,7 +47,7 @@ export class Shell implements IShell {
48
47
const ws = stream ? stream : this . e . log . createWriteStream ( LOGGER_LEVELS . INFO , false ) ;
49
48
50
49
try {
51
- const promise = cmd . run ( ) ;
50
+ const promise = proc . run ( ) ;
52
51
53
52
if ( promise . p . stdout ) {
54
53
const s = combineStreams ( split2 ( ) , ws ) ;
@@ -124,19 +123,17 @@ export class Shell implements IShell {
124
123
}
125
124
}
126
125
127
- async output ( command : string , args : string [ ] , { fatalOnNotFound = true , fatalOnError = true , showError = true , showCommand = false , ...crossSpawnOptions } : IShellOutputOptions ) : Promise < string > {
128
- const cmdpath = await this . resolveCommandPath ( command , crossSpawnOptions ) ;
129
- const cmd = new Subprocess ( cmdpath , args , crossSpawnOptions ) ;
130
-
131
- const fullCmd = cmd . bashify ( ) ;
126
+ async output ( command : string , args : readonly string [ ] , { fatalOnNotFound = true , fatalOnError = true , showError = true , showCommand = false , ...crossSpawnOptions } : IShellOutputOptions ) : Promise < string > {
127
+ const proc = await this . createSubprocess ( command , args , crossSpawnOptions ) ;
128
+ const fullCmd = proc . bashify ( ) ;
132
129
const truncatedCmd = fullCmd . length > 80 ? fullCmd . substring ( 0 , 80 ) + '...' : fullCmd ;
133
130
134
131
if ( showCommand && this . e . log . level >= LOGGER_LEVELS . INFO ) {
135
132
this . e . log . rawmsg ( `> ${ input ( fullCmd ) } ` ) ;
136
133
}
137
134
138
135
try {
139
- return await cmd . output ( ) ;
136
+ return await proc . output ( ) ;
140
137
} catch ( e ) {
141
138
if ( e instanceof SubprocessError && e . code === ERROR_COMMAND_NOT_FOUND ) {
142
139
if ( fatalOnNotFound ) {
@@ -188,35 +185,40 @@ export class Shell implements IShell {
188
185
return which ( command , { PATH : this . alterPath ( PATH || '' ) } ) ;
189
186
}
190
187
191
- async spawn ( command : string , args : string [ ] , { showCommand = true , ...crossSpawnOptions } : IShellSpawnOptions ) : Promise < ChildProcess > {
188
+ async spawn ( command : string , args : readonly string [ ] , { showCommand = true , ...crossSpawnOptions } : IShellSpawnOptions ) : Promise < ChildProcess > {
192
189
this . prepareSpawnOptions ( crossSpawnOptions ) ;
193
190
194
- const cmdpath = await this . resolveCommandPath ( command , crossSpawnOptions ) ;
195
- const cmd = new Subprocess ( cmdpath , args , crossSpawnOptions ) ;
196
- const p = cmd . spawn ( ) ;
191
+ const proc = await this . createSubprocess ( command , args , crossSpawnOptions ) ;
192
+ const p = proc . spawn ( ) ;
197
193
198
194
if ( showCommand && this . e . log . level >= LOGGER_LEVELS . INFO ) {
199
- this . e . log . rawmsg ( `> ${ input ( cmd . bashify ( ) ) } ` ) ;
195
+ this . e . log . rawmsg ( `> ${ input ( proc . bashify ( ) ) } ` ) ;
200
196
}
201
197
202
198
return p ;
203
199
}
204
200
205
- async cmdinfo ( command : string , args : string [ ] = [ ] ) : Promise < string | undefined > {
201
+ async cmdinfo ( command : string , args : readonly string [ ] = [ ] ) : Promise < string | undefined > {
206
202
const opts : IShellSpawnOptions = { } ;
207
203
this . prepareSpawnOptions ( opts ) ;
208
204
209
- const cmdpath = await this . resolveCommandPath ( command , opts ) ;
210
- const cmd = new Subprocess ( cmdpath , args , opts ) ;
205
+ const proc = await this . createSubprocess ( command , args , opts ) ;
211
206
212
207
try {
213
- const out = await cmd . output ( ) ;
208
+ const out = await proc . output ( ) ;
214
209
return out . split ( '\n' ) . join ( ' ' ) . trim ( ) ;
215
210
} catch ( e ) {
216
211
// no command info at this point
217
212
}
218
213
}
219
214
215
+ async createSubprocess ( command : string , args : readonly string [ ] = [ ] , options : SubprocessOptions = { } ) : Promise < Subprocess > {
216
+ const cmdpath = await this . resolveCommandPath ( command , options ) ;
217
+ const proc = new Subprocess ( cmdpath , args , options ) ;
218
+
219
+ return proc ;
220
+ }
221
+
220
222
protected prepareSpawnOptions ( options : IShellSpawnOptions ) {
221
223
// Create a `process.env`-type object from all key/values of `process.env`,
222
224
// then `options.env`, then add several key/values. PATH is supplemented
0 commit comments