11'use strict' ;
22
33var fs = require ( 'fs' ) ,
4- path = require ( 'path' ) ,
5- through = require ( 'through2' ) ,
4+ path = require ( 'path' ) ;
5+
6+ var through = require ( 'through2' ) ,
67 merge = require ( 'lodash.merge' ) ,
78 trackFilenames = require ( 'gulp-track-filenames' ) ,
89 transformTools = require ( 'browserify-transform-tools' ) ,
@@ -22,7 +23,7 @@ var fs = require('fs'),
2223function isLiteralAST ( node ) {
2324 var candidates = Array . prototype . slice . call ( arguments , 1 ) ;
2425 return ( node ) && ( node . type === 'Literal' ) && candidates . some ( function ( candidate ) {
25- return ( node . value === candidate )
26+ return ( node . value === candidate ) ;
2627 } ) ;
2728}
2829
@@ -49,7 +50,7 @@ function isMethodAST(node) {
4950 * @return A jasmine transform
5051 */
5152function jasmineTransform ( symbol ) {
52- return transformTools . makeFalafelTransform ( 'jasmineTransform' , null , function ( node , options , done ) {
53+ return transformTools . makeFalafelTransform ( 'jasmineTransform' , null , function jasmineASTWalker ( node , options , done ) {
5354 var isValid = isLiteralAST ( node , symbol ) && isMethodAST ( node . parent , 'describe' , 'module' ) ;
5455 if ( isValid ) {
5556 node . update ( '\'' + options . file . replace ( / \\ / g, '\\\\' ) + ':0:0\'' ) ;
@@ -112,11 +113,11 @@ function compile(bannerWidth, transforms) {
112113 * @return {string } The transformed file path
113114 */
114115 function rootRelative ( filePath , i , array ) {
115- var rootRelative = slash ( path . relative ( process . cwd ( ) , path . resolve ( filePath ) ) ) ; // resolve relative references
116- var isProject = ( rootRelative . slice ( 0 , 2 ) !== '..' ) ;
117- var result = [
116+ var rootRelPath = slash ( path . relative ( process . cwd ( ) , path . resolve ( filePath ) ) ) ; // resolve relative references
117+ var isProject = ( rootRelPath . slice ( 0 , 2 ) !== '..' ) ;
118+ var result = [
118119 sourceMapBase || '' ,
119- isProject ? rootRelative : path . basename ( rootRelative )
120+ isProject ? rootRelPath : path . basename ( rootRelPath )
120121 ] . join ( path . sep ) ;
121122 if ( ( typeof i === 'number' ) && ( typeof array === 'object' ) ) {
122123 array [ i ] = result ;
@@ -130,7 +131,7 @@ function compile(bannerWidth, transforms) {
130131 var BOWER = path . relative ( process . cwd ( ) , bowerDir . sync ( ) ) ;
131132 return transformTools . makeRequireTransform ( 'requireTransform' , null , function ( args , opts , done ) {
132133
133- // transform the original path where relevent
134+ // transform the original path where relevant
134135 var original = args [ 0 ] ;
135136 var split = original . split ( / [ \\ \/ ] / g) ; // keep delimiters
136137 var firstTerm = split . splice ( 0 , 1 ) [ 0 ] ; // remove the first term from the split
@@ -178,39 +179,57 @@ function compile(bannerWidth, transforms) {
178179 // error handler
179180 var timeout ;
180181 function errorHandler ( error ) {
181- var text = error . toString ( ) ;
182- var analysis ;
183- var message ;
184-
185- // SyntaxError: <file>:<reason>:<line>:<column>
186- if ( analysis = / ^ \s * S y n t a x E r r o r \: \s * ( [ ^ : ] * ) \s * \: \s * ( [ ^ ( ] * ) \s * \( ( \d + : \d + ) \) \s * \n / . exec ( text ) ) {
187- message = [ analysis [ 1 ] , analysis [ 3 ] , analysis [ 2 ] ] . join ( ':' ) + '\n' ;
188-
189- // Error: SyntaxError: <reason> while parsing json file <file>
190- } else if ( analysis = / ^ \s * E r r o r : S y n t a x E r r o r \: \s * ( .* ) \s * w h i l e p a r s i n g j s o n f i l e \s * ( [ ^ ] * ) / . exec ( text ) ) {
191- message = [ analysis [ 2 ] , '0' , '0' , ' ' + analysis [ 1 ] ] . join ( ':' ) + '\n' ;
192-
193- // Line <line>: <reason>: <file>
194- } else if ( analysis = / L i n e \s * ( \d + ) \s * \: \s * ( [ ^ : ] * ) \s * : \s * ( .* ) \s * / . exec ( text ) ) {
195- message = [ analysis [ 3 ] , analysis [ 1 ] , 0 , ' ' + analysis [ 2 ] ] . join ( ':' ) + '\n' ;
196-
197- // Error: Cannot find module '<reason>' from '<directory>'
198- // find the first text match for any text quoted in <reason>
199- } else if ( analysis = / ^ \s * E r r o r \: C a n n o t f i n d m o d u l e ' ( .* ) \' \s * f r o m \s * \' ( .* ) \' \s * $ / . exec ( text ) ) {
200- var filename = fs . readdirSync ( analysis [ 2 ] )
201- . filter ( RegExp . prototype . test . bind ( / \. j s $ / i) )
202- . filter ( function ( jsFilename ) {
203- var fullPath = path . join ( analysis [ 2 ] , jsFilename ) ;
204- var fileText = fs . readFileSync ( fullPath ) . toString ( ) ;
205- return ( new RegExp ( '[\'"]' + analysis [ 1 ] + '[\'"]' ) ) . test ( fileText ) ;
206- } )
207- . shift ( ) ;
208- message = path . join ( analysis [ 2 ] , filename ) + ':0:0: Cannot find import ' + analysis [ 1 ] + '\n' ;
209-
210- // Unknown
211- } else {
212- message = 'TODO parse this error\n' + text + '\n' ;
213- }
182+
183+ // run a bunch of tests against the error in order to determine the appropriate error message
184+ // there will be at least one truthy value, even if that is the final placeholder
185+ var text = error . toString ( ) ;
186+ var message = [
187+
188+ // SyntaxError: <file>:<reason>:<line>:<column>
189+ function testSyntaxError ( ) {
190+ var analysis = / ^ \s * S y n t a x E r r o r \: \s * ( [ ^ : ] * ) \s * \: \s * ( [ ^ ( ] * ) \s * \( ( \d + : \d + ) \) \s * \n / . exec ( text ) ;
191+ return analysis && ( [ analysis [ 1 ] , analysis [ 3 ] , analysis [ 2 ] ] . join ( ':' ) + '\n' ) ;
192+ } ,
193+
194+ // Error: SyntaxError: <reason> while parsing json file <file>
195+ function testSyntaxErrorJSON ( ) {
196+ var analysis = / ^ \s * E r r o r : S y n t a x E r r o r \: \s * ( .* ) \s * w h i l e p a r s i n g j s o n f i l e \s * ( [ ^ ] * ) / . exec ( text ) ;
197+ return analysis && ( [ analysis [ 2 ] , '0' , '0' , ' ' + analysis [ 1 ] ] . join ( ':' ) + '\n' ) ;
198+ } ,
199+
200+ // Line <line>: <reason>: <file>
201+ function testGeneric ( ) {
202+ var analysis = / L i n e \s * ( \d + ) \s * \: \s * ( [ ^ : ] * ) \s * : \s * ( .* ) \s * / . exec ( text ) ;
203+ return analysis && ( [ analysis [ 3 ] , analysis [ 1 ] , 0 , ' ' + analysis [ 2 ] ] . join ( ':' ) + '\n' ) ;
204+ } ,
205+
206+ // Error: Cannot find module '<reason>' from '<directory>'
207+ // find the first text match for any text quoted in <reason>
208+ function testBadImport ( ) {
209+ var analysis = / ^ \s * E r r o r \: C a n n o t f i n d m o d u l e ' ( .* ) \' \s * f r o m \s * \' ( .* ) \' \s * $ / . exec ( text ) ;
210+ if ( analysis ) {
211+ var filename = fs . readdirSync ( analysis [ 2 ] )
212+ . filter ( RegExp . prototype . test . bind ( / \. j s $ / i) )
213+ . filter ( function ( jsFilename ) {
214+ var fullPath = path . join ( analysis [ 2 ] , jsFilename ) ;
215+ var fileText = fs . readFileSync ( fullPath ) . toString ( ) ;
216+ return ( new RegExp ( '[\'"]' + analysis [ 1 ] + '[\'"]' ) ) . test ( fileText ) ;
217+ } )
218+ . shift ( ) ;
219+ return path . join ( analysis [ 2 ] , filename ) + ':0:0: Cannot find import ' + analysis [ 1 ] + '\n' ;
220+ }
221+ } ,
222+
223+ // Unknown
224+ function otherwise ( ) {
225+ return 'TODO parse this error\n' + text + '\n' ;
226+ }
227+ ]
228+ . map ( function invokeTestMethod ( testMethod ) {
229+ return testMethod ( ) ;
230+ } )
231+ . filter ( Boolean )
232+ . shift ( ) ;
214233
215234 // add unique
216235 if ( output . indexOf ( message ) < 0 ) {
@@ -238,7 +257,7 @@ function compile(bannerWidth, transforms) {
238257 // transforms
239258 transforms
240259 . concat ( requireTransform ( false ) )
241- . forEach ( function ( item , i , list ) {
260+ . forEach ( function eachItem ( item , i , list ) {
242261 if ( typeof item === 'function' ) {
243262 var opts = ( typeof list [ i + 1 ] === 'object' ) ? merge ( { global : true } , list [ i + 1 ] ) : { global : true } ;
244263 bundler . transform ( item , opts ) ;
@@ -247,7 +266,7 @@ function compile(bannerWidth, transforms) {
247266
248267 // require statements
249268 [ ] . concat ( files )
250- . forEach ( function ( item ) {
269+ . forEach ( function eachItem ( item ) {
251270 bundler . require ( item , { entry : true } ) ;
252271 } ) ;
253272
@@ -258,7 +277,7 @@ function compile(bannerWidth, transforms) {
258277 uglify : {
259278 compress : { // anything that changes semicolons to commas will cause debugger problems
260279 sequences : false ,
261- join_vars : false
280+ join_vars : false // jshint ignore:line
262281 } ,
263282 mangle : {
264283 toplevel : true
@@ -269,7 +288,7 @@ function compile(bannerWidth, transforms) {
269288
270289 // when we use minification we will get: error, code, source-map
271290 // when we don't we will get: error, buffer(with embedded source map)
272- bundler . bundle ( function ( error , codeOrBuffer , map ) {
291+ bundler . bundle ( function onComplete ( error , codeOrBuffer , map ) {
273292 if ( ! error ) {
274293 var code = codeOrBuffer . toString ( ) ;
275294 var sourceMap = map ? JSON . parse ( map ) : convert . fromComment ( code ) . toObject ( ) ;
@@ -296,10 +315,10 @@ function compile(bannerWidth, transforms) {
296315 * @param {string } [sourceMapBase] Base path for source map file
297316 * @returns {stream.Through }
298317 */
299- each : function ( isMinify , sourceMapBase ) {
300- return through . obj ( function ( file , encoding , done ) {
318+ each : function gulpBundleEach ( isMinify , sourceMapBase ) {
319+ return through . obj ( function transformFn ( file , encoding , done ) {
301320 bundle ( this , [ file . path ] , file . relative , isMinify , sourceMapBase , done ) ;
302- } , function ( done ) {
321+ } , function flushFn ( done ) {
303322 flushErrors ( ) ;
304323 done ( ) ;
305324 } ) ;
@@ -312,12 +331,12 @@ function compile(bannerWidth, transforms) {
312331 * @param {string } [sourceMapBase] Base path for source map file
313332 * @returns {stream.Through }
314333 */
315- all : function ( outPath , isMinify , sourceMapBase ) {
334+ all : function gulpBundleAll ( outPath , isMinify , sourceMapBase ) {
316335 var pending = [ ] ;
317- return through . obj ( function ( file , encoding , done ) {
336+ return through . obj ( function transformFn ( file , encoding , done ) {
318337 pending . push ( file . path ) ;
319338 done ( ) ;
320- } , function ( done ) {
339+ } , function flushFn ( done ) {
321340 if ( pending . length ) {
322341 bundle ( this , pending , outPath , isMinify , sourceMapBase , function ( ) {
323342 flushErrors ( ) ;
0 commit comments