@@ -106,7 +106,8 @@ function pluginFn(grunt: IGrunt) {
106
106
verbose : false ,
107
107
fast : 'watch' ,
108
108
htmlModuleTemplate : '<%= filename %>' ,
109
- htmlVarTemplate : '<%= ext %>'
109
+ htmlVarTemplate : '<%= ext %>' ,
110
+ failOnTypeErrors : true
110
111
} ) ;
111
112
112
113
// get unprocessed templates from configuration
@@ -229,16 +230,62 @@ function pluginFn(grunt: IGrunt) {
229
230
// End the timer
230
231
endtime = new Date ( ) . getTime ( ) ;
231
232
232
- // Evaluate the result
233
- if ( ! result || result . code ) {
234
- grunt . log . error ( 'Compilation failed' . red ) ;
233
+ grunt . log . writeln ( '' ) ;
234
+
235
+ // Analyze the results of our tsc execution,
236
+ // then tell the user our analysis results
237
+ // and mark the build as fail or success
238
+ if ( ! result ) {
239
+ grunt . log . error ( 'Error: No result from tsc.' . red ) ;
235
240
return false ;
236
241
}
237
- else {
242
+
243
+ var isError = ( result . code === 1 ) ;
244
+
245
+ // If the compilation errors contain only type errors, JS files are still
246
+ // generated. If tsc finds type errors, it will return an error code, even
247
+ // if JS files are generated. We should check this for this,
248
+ // only type errors, and call this a successful compilation.
249
+ // Assumptions:
250
+ // Level 1 errors = syntax errors - prevent JS emit.
251
+ // Level 2 errors = semantic errors - *not* prevents JS emit.
252
+ // Level 5 errors = compiler flag misuse - prevents JS emit.
253
+ var hasPreventEmitErrors = _ . foldl ( result . output . split ( '\n' ) , function ( memo , errorMsg : string ) {
254
+ var hasLevel1Errors = errorMsg . search ( / e r r o r T S 1 \d + : / g) >= 0 ;
255
+ // var hasLevel2PlusErrors = errorMsg.search(/error TS[2-4,6-9]\d+:/g) >= 0;
256
+ var hasLevel5Errors = errorMsg . search ( / e r r o r T S 5 \d + : / ) >= 0 ;
257
+ return memo || ( hasLevel1Errors || hasLevel5Errors ) ;
258
+ } , false ) || false ;
259
+
260
+ // Because we can't think of a better way to determine it,
261
+ // assume that emitted JS in spite of error codes implies type-only errors.
262
+ var isOnlyTypeErrors = ! hasPreventEmitErrors ;
263
+
264
+ // Explain our interpretation of the tsc errors before we mark build results.
265
+ if ( isError ) {
266
+ if ( isOnlyTypeErrors ) {
267
+ grunt . log . writeln ( 'Type errors only.' ) ;
268
+ }
269
+ }
270
+
271
+ // !!! To do: To really be confident that the build was actually successful,
272
+ // we have to check timestamps of the generated files in the destination.
273
+ var isSuccessfulBuild = ( ! isError ||
274
+ ( isError && isOnlyTypeErrors && ! options . failOnTypeErrors )
275
+ ) ;
276
+
277
+ if ( isSuccessfulBuild ) {
278
+ // Report successful build.
238
279
var time = ( endtime - starttime ) / 1000 ;
239
- grunt . log . writeln ( ( 'Success: ' + time . toFixed ( 2 ) + 's for ' + result . fileCount + ' typescript files' ) . green ) ;
240
- return true ;
280
+ grunt . log . writeln ( '' ) ;
281
+ grunt . log . writeln ( ( 'TypeScript compilation complete: ' + time . toFixed ( 2 ) +
282
+ 's for ' + result . fileCount + ' typescript files' ) . green ) ;
283
+ } else {
284
+ // Report unsuccessful build.
285
+ grunt . log . error ( ( 'Error: tsc return code: ' + result . code ) . yellow ) ;
241
286
}
287
+
288
+ return isSuccessfulBuild ;
242
289
} ) ;
243
290
}
244
291
0 commit comments