@@ -29,43 +29,49 @@ var resolvedReporter;
2929 * @return {function } The `required`ed jshint report, ready to be piped a gulp stream
3030 */
3131function getJsHintReporter ( reporterName ) {
32-
3332 // establish a cached copy
3433 if ( ! resolvedReporter ) {
3534 if ( typeof reporterName !== 'string' ) {
3635 throw 'Get JsHint Reporter: Reporter name is unspecified' ;
3736 }
3837 else {
38+ var reporterPath ;
39+
3940 // first check angularity installed modules, then check project locally installed modules
40- [ path . resolve ( 'node_modules' ) , null ] . forEach ( function ( base ) {
41- var reporterPath = base ? path . join ( base , reporterName ) : reporterName ;
42- try {
43- // In JsHint convention, the `index.js` file exports a string which jshint itself should require
41+ [ ( path . resolve ( 'node_modules' ) ) , undefined ] . forEach ( function ( baseDir ) {
42+ reporterPath = ( ! ! baseDir ) ? path . join ( baseDir , reporterName ) : reporterName ;
43+ try {
44+ var indirect = require ( reporterPath ) ;
45+ if ( Object . prototype . toString . call ( indirect ) === '[object Object]' ) {
46+ // In newer JsHint convention, the `index.js` file exports the object with the reporter functions directly
47+ // e.g. `modules.exports = { reporter: function( /* ... */ ) { /* ... */ } };`
48+ resolvedReporter = indirect ;
49+ }
50+ else if ( typeof indirect === 'string' ) {
51+ // In legacy JsHint convention, the `index.js` file exports a string which jshint itself should require
4452 // e.g. `module.exports = require('path').join(__dirname, 'reporter.js');`
45- // this is the indirect case.
46- // However in some cases it may be the reporter itself
47- var indirect = require ( reporterPath ) ;
48- resolvedReporter = ( typeof indirect === 'string' ) ? require ( indirect ) : indirect ;
49- } catch ( ex ) {
50- /* do nothing */
53+ resolvedReporter = require ( indirect ) ;
5154 }
52- } ) ;
55+ }
56+ catch ( ex ) {
57+ // Do nothing: Handled outside loop when resolvedReporter not set
58+ }
59+ } ) ;
5360 if ( ! resolvedReporter ) {
54- throw 'Get JsHint Reporter: Attempt to require reporter from path ' + reporterPath + ' with no success.';
61+ throw 'Get JsHint Reporter: Attempt to require specified reporter with no success.' ;
5562 }
5663 }
5764 }
5865
5966 // return cached copy
60- // closure that returns a stream
61- if ( typeof resolvedReporter === 'function' ) {
62- return resolvedReporter ( ) ;
67+ if ( ! ! resolvedReporter && ( typeof resolvedReporter . streamReporter === 'function' ) ) {
68+ // Streaming reporters can get instantiated directly
69+ return resolvedReporter . streamReporter ( ) ;
6370 }
64- // jshint plugin object with reporter field
65- else if ( ! ! ( resolvedReporter ) && ( typeof resolvedReporter . reporter === 'function' ) ) {
71+ else if ( ! ! resolvedReporter && ( typeof resolvedReporter . reporter === 'function' ) ) {
72+ // Standard JsHint reporters need to be wrapped by gulp-jshint
6673 return gulpJshint . reporter ( resolvedReporter ) ;
6774 }
68- // unsupported
6975 else {
7076 throw 'Get JsHint Reporter: Given reporter is badly formed' ;
7177 }
0 commit comments