@@ -12,13 +12,22 @@ common.register('exec', _exec, {
12
12
unix : false ,
13
13
canReceivePipe : true ,
14
14
wrapOutput : false ,
15
+ handlesFatalDynamically : true ,
15
16
} ) ;
16
17
17
18
// We use this function to run `exec` synchronously while also providing realtime
18
19
// output.
19
20
function execSync ( cmd , opts , pipe ) {
20
21
if ( ! common . config . execPath ) {
21
- common . error ( 'Unable to find a path to the node binary. Please manually set config.execPath' ) ;
22
+ try {
23
+ common . error ( 'Unable to find a path to the node binary. Please manually set config.execPath' ) ;
24
+ } catch ( e ) {
25
+ if ( opts . fatal ) {
26
+ throw e ;
27
+ }
28
+
29
+ return ;
30
+ }
22
31
}
23
32
24
33
var tempDir = _tempDir ( ) ;
@@ -28,6 +37,7 @@ function execSync(cmd, opts, pipe) {
28
37
29
38
opts = common . extend ( {
30
39
silent : common . config . silent ,
40
+ fatal : common . config . fatal , // TODO(nfischer): this and the line above are probably unnecessary
31
41
cwd : _pwd ( ) . toString ( ) ,
32
42
env : process . env ,
33
43
maxBuffer : DEFAULT_MAXBUFFER_SIZE ,
@@ -99,7 +109,7 @@ function execSync(cmd, opts, pipe) {
99
109
// Note: `silent` should be unconditionally true to avoid double-printing
100
110
// the command's stderr, and to avoid printing any stderr when the user has
101
111
// set `shell.config.silent`.
102
- common . error ( stderr , code , { continue : true , silent : true } ) ;
112
+ common . error ( stderr , code , { continue : true , silent : true , fatal : opts . fatal } ) ;
103
113
}
104
114
var obj = common . ShellString ( stdout , stderr , code ) ;
105
115
return obj ;
@@ -109,6 +119,7 @@ function execSync(cmd, opts, pipe) {
109
119
function execAsync ( cmd , opts , pipe , callback ) {
110
120
opts = common . extend ( {
111
121
silent : common . config . silent ,
122
+ fatal : common . config . fatal , // TODO(nfischer): this and the line above are probably unnecessary
112
123
cwd : _pwd ( ) . toString ( ) ,
113
124
env : process . env ,
114
125
maxBuffer : DEFAULT_MAXBUFFER_SIZE ,
@@ -146,6 +157,7 @@ function execAsync(cmd, opts, pipe, callback) {
146
157
//@
147
158
//@ + `async`: Asynchronous execution. If a callback is provided, it will be set to
148
159
//@ `true`, regardless of the passed value (default: `false`).
160
+ //@ + `fatal`: Exit upon error (default: `false`).
149
161
//@ + `silent`: Do not echo program output to console (default: `false`).
150
162
//@ + `encoding`: Character encoding to use. Affects the values returned to stdout and stderr, and
151
163
//@ what is written to stdout and stderr when not in silent mode (default: `'utf8'`).
@@ -184,7 +196,6 @@ function execAsync(cmd, opts, pipe, callback) {
184
196
//@ Guidelines](https://github.com/shelljs/shelljs/wiki/Security-guidelines).
185
197
function _exec ( command , options , callback ) {
186
198
options = options || { } ;
187
- if ( ! command ) common . error ( 'must specify command' ) ;
188
199
189
200
var pipe = common . readFromPipe ( ) ;
190
201
@@ -201,9 +212,22 @@ function _exec(command, options, callback) {
201
212
202
213
options = common . extend ( {
203
214
silent : common . config . silent ,
215
+ fatal : common . config . fatal ,
204
216
async : false ,
205
217
} , options ) ;
206
218
219
+ if ( ! command ) {
220
+ try {
221
+ common . error ( 'must specify command' ) ;
222
+ } catch ( e ) {
223
+ if ( options . fatal ) {
224
+ throw e ;
225
+ }
226
+
227
+ return ;
228
+ }
229
+ }
230
+
207
231
if ( options . async ) {
208
232
return execAsync ( command , options , pipe , callback ) ;
209
233
} else {
0 commit comments