@@ -11,58 +11,69 @@ var combined = require('combined-stream'),
1111 fs = require ( 'fs' ) ;
1212
1313/**
14- * @param { string|RegExp } pattern Matches the extension of bower files
15- * @param {object? } options Options for <code>gulp.src()</code> stream
14+ * Create a gulp.src() method that emits the bower main files and optional version manifest.
15+ * @param {{pattern:string, base:boolean, manifest:boolean, dev:boolean} } Options
1616 */
17- module . exports = function src ( pattern , options ) {
18- options = options || { } ;
19-
20- // create result list
21- // the parsed content will be sorted by extension
22- var parsed = json ( options . dev ) ,
23- manifestFile = ! ! options . manifest && manifest ( options . manifest === 'comment' , options . dev ) ,
24- bowerPackages = [ ] ;
25- for ( var packageName in parsed ) {
26- var config = parsed [ packageName ] ,
27- list = [ ]
28- . concat ( config . main )
29- . filter ( Boolean )
30- . map ( toAbsoluteForPackage ( packageName ) )
31- . filter ( testExtension ) ;
32- if ( list . length ) {
33- var base = list . reduce ( greatestCommonBase , null ) ;
34- bowerPackages . push ( {
35- name : packageName ,
36- options : defaults ( { base : base || options . base } , options ) , // use our base over that given
37- list : list
38- } ) ;
17+ module . exports = function create ( options ) {
18+ defaults ( options , {
19+ pattern : '*' ,
20+ base : false ,
21+ manifest : false ,
22+ dev : false
23+ } ) ;
24+
25+ /**
26+ * Get a gulp.src() stream for the bower main files.
27+ * @param {object } options Options for <code>gulp.src()</code> stream
28+ */
29+ return function src ( gulpSrcOptions ) {
30+
31+ // create result list
32+ var parsed = json ( options . dev , options . context ) ,
33+ manifestFile = ! ! options . manifest && manifest ( ( options . manifest === 'comment' ) , options . dev ) ,
34+ bowerPackages = [ ] ;
35+ for ( var packageName in parsed ) {
36+ var config = parsed [ packageName ] ,
37+ list = [ ]
38+ . concat ( config . main )
39+ . filter ( Boolean )
40+ . map ( toAbsoluteForPackage ( packageName ) )
41+ . filter ( testExtension ) ;
42+ if ( list . length ) {
43+ var base = list . reduce ( greatestCommonBase , null ) ;
44+ bowerPackages . push ( {
45+ name : packageName ,
46+ options : defaults ( { base : base || options . base } , gulpSrcOptions ) , // use our base over that given
47+ list : list
48+ } ) ;
49+ }
3950 }
40- }
4151
42- // represent list as a readable stream, even if empty
43- var stream ;
52+ // represent list as a readable stream, even if empty
53+ var stream ;
4454
45- // degenerate stream
46- if ( ! bowerPackages . length ) {
47- stream = spigot ( { objectMode : true } , [ ] ) ;
48- stream . _read = function ( ) {
49- } ;
50- stream . push ( null ) ;
51- }
52- // combination of source streams with specific base path for each package
53- else {
54- stream = combined . create ( ) ;
55- if ( manifestFile ) {
56- stream . append ( manifestFile ) ;
55+ // degenerate stream
56+ if ( ! bowerPackages . length ) {
57+ stream = spigot ( { objectMode : true } , [ ] ) ;
58+ stream . _read = function ( ) {
59+ } ;
60+ stream . push ( null ) ;
61+ }
62+ // combination of source streams with specific base path for each package
63+ else {
64+ stream = combined . create ( ) ;
65+ if ( manifestFile ) {
66+ stream . append ( manifestFile ) ;
67+ }
68+ bowerPackages . reduce ( eachPackage , stream ) ;
5769 }
58- bowerPackages . reduce ( eachPackage , stream ) ;
59- }
6070
61- // add the list to the stream as a sidecar
62- stream . list = flatten ( bowerPackages ) ;
71+ // add the list to the stream as a sidecar
72+ stream . list = flatten ( bowerPackages ) ;
6373
64- // complete
65- return stream ;
74+ // complete
75+ return stream ;
76+ } ;
6677
6778 function greatestCommonBase ( candidate , absolute ) {
6879 if ( candidate ) {
@@ -95,7 +106,8 @@ module.exports = function src(pattern, options) {
95106 }
96107
97108 function testExtension ( filename ) {
98- var ext = path . extname ( filename ) . slice ( 1 ) ;
109+ var pattern = options . pattern ,
110+ ext = path . extname ( filename ) . slice ( 1 ) ;
99111 return (
100112 ( ( typeof pattern === 'string' ) && ( pattern . split ( '|' ) . indexOf ( ext ) >= 0 ) ) ||
101113 ( ( typeof pattern === 'object' ) && ( 'test' in pattern ) && pattern . test ( ext ) ) ||
@@ -111,13 +123,15 @@ function toAbsoluteForPackage(packageName) {
111123}
112124
113125/**
114- * Retrieve version details of bower files as a stream
115- * @param {boolean } useComment Determines whether the output is wrapped in a comment
126+ * Retrieve version details of bower files as a stream.
116127 * @param {boolean } includeDev Determines whether dev dependencies are included
128+ * @param {string } context Key used to determine overrides
117129 * @returns {stream.Readable } A readable stream containing only the manifest file
118130 */
119- function json ( includeDev ) {
120- return processBowerJson ( read ( 'bower.json' ) , includeDev ) ;
131+ function json ( includeDev , context ) {
132+ var root = read ( 'bower.json' ) ,
133+ packages = reduceJsonToPackages ( root , includeDev ) ;
134+ return processOverrides ( packages , root . overrides ) ;
121135
122136 function read ( filename ) {
123137 try {
@@ -127,23 +141,35 @@ function json(includeDev) {
127141 }
128142 }
129143
130- function processBowerJson ( json , includeDev ) {
144+ function reduceJsonToPackages ( json , includeDev ) {
131145 var isValid = ( json && ( typeof json === 'object' ) ) ,
132146 dependencies = isValid && defaults ( json . dependencies , includeDev && json . devDependencies ) || { } ;
133147 return Object . keys ( dependencies )
134- . reduce ( reduceDeps , { } ) ;
148+ . reduce ( reduceDependencies , { } ) ;
149+
150+ function reduceDependencies ( result , packageName ) {
151+ var contents = read ( path . join ( 'bower_components' , packageName , 'bower.json' ) ) ;
152+ defaults ( result , reduceJsonToPackages ( contents , false ) ) ; // current items' dependencies precede the current item
153+ result [ packageName ] = contents ;
154+ return result ;
155+ }
135156 }
136157
137- function reduceDeps ( result , key ) {
138- var contents = read ( path . join ( 'bower_components' , key , 'bower.json' ) ) ;
139- defaults ( result , processBowerJson ( contents , false ) ) ; // current items' dependencies precede the current item
140- result [ key ] = contents ;
141- return result ;
158+ function processOverrides ( packages , overrides ) {
159+ return Object . keys ( packages )
160+ . reduce ( reducePackages , { } ) ;
161+
162+ function reducePackages ( result , packageName ) {
163+ var item = packages [ packageName ] ,
164+ override = overrides [ packageName + '.' + context ] || overrides [ packageName ] ;
165+ result [ packageName ] = defaults ( { } , override , item ) ;
166+ return result ;
167+ }
142168 }
143169}
144170
145171/**
146- * Retrieve version details of bower files as a stream
172+ * Retrieve version details of bower files as a stream.
147173 * @param {boolean } useComment Determines whether the output is wrapped in a comment
148174 * @param {boolean } includeDev Determines whether dev dependencies are included
149175 * @returns {stream.Readable } A readable stream containing only the manifest file
0 commit comments