1+ 'use strict' ;
2+ const core = require ( './core' ) ;
3+ const path = require ( 'path' ) ;
4+ const yaml = require ( 'js-yaml' ) ;
5+ const fs = require ( 'fs' ) ;
6+ const inject = require ( 'gulp-inject' ) ;
7+ const _ = require ( 'lodash' ) ;
8+ const browserSync = require ( 'browser-sync' ) ;
9+ const glob = require ( 'glob' ) ;
10+
11+ module . exports = ( gulp , config , tasks ) => {
12+ let plConfig = yaml . safeLoad (
13+ fs . readFileSync ( config . patternLab . configFile , 'utf8' )
14+ ) ;
15+ const plRoot = path . join ( config . patternLab . configFile , '../..' ) ;
16+ const plSource = path . join ( plRoot , plConfig . sourceDir ) ;
17+ const plPublic = path . join ( plRoot , plConfig . publicDir ) ;
18+ const plMeta = path . join ( plSource , '/_meta' ) ;
19+ const consolePath = path . join ( plRoot , 'core/console' ) ;
20+ const watchTriggeredTasks = [ ] ;
21+
22+ function plBuild ( done , errorShouldExit ) {
23+ core . sh ( `php ${ consolePath } --generate` , errorShouldExit , ( err ) => {
24+ if ( config . browserSync . enabled ) {
25+ browserSync . get ( 'server' ) . reload ( ) ;
26+ }
27+ done ( err ) ;
28+ } ) ;
29+ }
30+
31+ gulp . task ( 'pl' , done => plBuild ( done , true ) ) ;
32+
33+ // Begin `<link>` & `<script>` injecting code.
34+ // Will look for these HTML comments in `plSource/_meta/*.twig:
35+ // `<!-- inject:css -->`
36+ // `<!-- endinject -->`
37+ // `<!-- inject:js -->`
38+ // `<!-- endinject -->`
39+
40+ function injectPl ( done ) {
41+ let sources = [ ] ;
42+ if ( config . patternLab . injectFiles ) {
43+ sources = sources . concat ( config . patternLab . injectFiles ) ;
44+ }
45+ console . log ( config . js . dest ) ;
46+ sources = sources . concat ( glob . sync ( path . normalize ( `${ config . js . dest } /*.js` ) ) ) ;
47+ sources = sources . concat ( glob . sync ( path . normalize ( `${ config . css . dest } /*.css` ) ) ) ;
48+ // We need to make sure our JS deps like jQuery are loaded before ours (`config.js.destName`)
49+ const rearrangedSources = [ ] ;
50+ sources . forEach ( ( source ) => {
51+ if ( path . basename ( source ) === config . js . destName ) {
52+ // add to end
53+ rearrangedSources . push ( source ) ;
54+ } else {
55+ // add to beginning
56+ rearrangedSources . unshift ( source ) ;
57+ }
58+ } ) ;
59+
60+ gulp
61+ . src ( [ '*.twig' ] , { cwd : plMeta } )
62+ . pipe ( inject ( gulp . src ( rearrangedSources , { read : false } ) , {
63+ relative : false ,
64+ addRootSlash : false ,
65+ addSuffix : '?cacheBuster={{ cacheBuster }}' ,
66+ addPrefix : path . join ( '../..' , path . relative ( plPublic , process . cwd ( ) ) ) ,
67+ } ) )
68+ . pipe ( gulp . dest ( plMeta ) )
69+ . on ( 'end' , done ) ;
70+ }
71+
72+ gulp . task ( 'inject:pl' , injectPl ) ;
73+
74+ const plFullDependencies = [ 'inject:pl' ] ;
75+
76+ // turns scss files full of variables into json files that PL can iterate on
77+ function scssToJson ( done ) {
78+ config . patternLab . scssToJson . forEach ( ( pair ) => {
79+ const scssVarList = _ . filter ( fs . readFileSync ( pair . src , 'utf8' ) . split ( '\n' ) , item => _ . startsWith ( item , pair . lineStartsWith ) ) ;
80+ // console.log(scssVarList, item.src);
81+ let varsAndValues = _ . map ( scssVarList , ( item ) => {
82+ // assuming `item` is `$color-gray: hsl(0, 0%, 50%); // main gray color`
83+ const x = item . split ( ':' ) ;
84+ const y = x [ 1 ] . split ( ';' ) ;
85+ return {
86+ name : x [ 0 ] . trim ( ) , // i.e. $color-gray
87+ value : y [ 0 ] . replace ( / ! .* / , '' ) . trim ( ) , // i.e. hsl(0, 0%, 50%) after removing `!default`
88+ comment : y [ 1 ] . replace ( '//' , '' ) . trim ( ) , // any inline comment coming after, i.e. `// main gray color`
89+ } ;
90+ } ) ;
91+
92+ if ( ! pair . allowVarValues ) {
93+ varsAndValues = _ . filter ( varsAndValues , item => ! _ . startsWith ( item . value , '$' ) ) ;
94+ }
95+
96+ fs . writeFileSync ( pair . dest , JSON . stringify ( {
97+ items : varsAndValues ,
98+ meta : {
99+ description : `To add to these items, use Sass variables that start with <code>${ pair . lineStartsWith } </code> in <code>${ pair . src } </code>` ,
100+ } ,
101+ } , null , ' ' ) ) ;
102+ } ) ;
103+ done ( ) ;
104+ }
105+
106+ if ( config . patternLab . scssToJson ) {
107+ gulp . task ( 'pl:scss-to-json' , scssToJson ) ;
108+ plFullDependencies . push ( 'pl:scss-to-json' ) ;
109+
110+ gulp . task ( 'watch:pl:scss-to-json' , ( ) => {
111+ const files = config . patternLab . scssToJson . map ( file => file . src ) ;
112+ gulp . watch ( files , scssToJson ) ;
113+ } ) ;
114+ tasks . watch . push ( 'watch:pl:scss-to-json' ) ;
115+ }
116+
117+ function getTwigNamespaceConfig ( workingDir ) {
118+ workingDir = workingDir || process . cwd ( ) ; // eslint-disable-line no-param-reassign
119+ const twigNamespaceConfig = { } ;
120+ config . patternLab . twigNamespaces . sets . forEach ( ( namespaceSet ) => {
121+ const pathArray = namespaceSet . paths . map ( ( pathBase ) => {
122+ const results = glob . sync ( path . join ( pathBase , '**/*.twig' ) ) . map ( ( pathItem ) => { // eslint-disable-line arrow-body-style
123+ return path . relative ( workingDir , path . dirname ( pathItem ) ) ;
124+ } ) ;
125+ results . unshift ( path . relative ( workingDir , pathBase ) ) ;
126+ return results ;
127+ } ) ;
128+ twigNamespaceConfig [ namespaceSet . namespace ] = {
129+ paths : core . uniqueArray ( core . flattenArray ( pathArray ) ) ,
130+ } ;
131+ } ) ;
132+ return twigNamespaceConfig ;
133+ }
134+
135+ function addTwigNamespaceConfigToDrupal ( done ) {
136+ const twigNamespaceConfig = getTwigNamespaceConfig ( path . dirname ( config . drupal . themeFile ) ) ;
137+ const drupalThemeFile = yaml . safeLoad (
138+ fs . readFileSync ( config . drupal . themeFile , 'utf8' )
139+ ) ;
140+ Object . assign ( drupalThemeFile [ 'component-libraries' ] , twigNamespaceConfig ) ;
141+ const newThemeFile = yaml . safeDump ( drupalThemeFile ) ;
142+ fs . writeFileSync ( config . drupal . themeFile , newThemeFile , 'utf8' ) ;
143+ done ( ) ;
144+ }
145+
146+ function addTwigNamespaceConfigToPl ( done ) {
147+ const twigNamespaceConfig = getTwigNamespaceConfig ( plRoot ) ;
148+ plConfig = yaml . safeLoad (
149+ fs . readFileSync ( config . patternLab . configFile , 'utf8' )
150+ ) ;
151+ if ( ! plConfig . plugins ) {
152+ Object . assign ( plConfig , {
153+ plugins : {
154+ twigNamespaces : { enabled : true , namespaces : { } } ,
155+ } ,
156+ } ) ;
157+ } else if ( ! plConfig . plugins . twigNamespaces ) {
158+ Object . assign ( plConfig . plugins , {
159+ twigNamespaces : { enabled : true , namespaces : { } } ,
160+ } ) ;
161+ } else if ( ! plConfig . plugins . twigNamespaces . namespaces ) {
162+ plConfig . plugins . twigNamespaces . namespaces = { } ;
163+ }
164+ Object . assign ( plConfig . plugins . twigNamespaces . namespaces , twigNamespaceConfig ) ;
165+ const newConfigFile = yaml . safeDump ( plConfig ) ;
166+ fs . writeFileSync ( config . patternLab . configFile , newConfigFile , 'utf8' ) ;
167+ done ( ) ;
168+ }
169+
170+ if ( config . patternLab . twigNamespaces ) {
171+ gulp . task ( 'twigNamespaces' , ( done ) => {
172+ addTwigNamespaceConfigToPl ( ( ) => {
173+ if ( config . patternLab . twigNamespaces . addToDrupalThemeFile ) {
174+ addTwigNamespaceConfigToDrupal ( done ) ;
175+ }
176+ done ( ) ;
177+ } ) ;
178+ } ) ;
179+ plFullDependencies . push ( 'twigNamespaces' ) ;
180+ watchTriggeredTasks . push ( 'twigNamespaces' ) ;
181+ }
182+
183+ gulp . task ( 'pl:full' , gulp . series ( plFullDependencies , plBuild ) ) ;
184+
185+ const watchedExtensions = config . patternLab . watchedExtensions . join ( ',' ) ;
186+ gulp . task ( 'watch:pl' , ( ) => {
187+ const plGlob = [ path . normalize ( `${ plSource } /**/*.{${ watchedExtensions } }` ) ] ;
188+ const src = config . patternLab . extraWatches
189+ ? [ ] . concat ( plGlob , config . patternLab . extraWatches )
190+ : plGlob ;
191+ // plBuild goes last after any deps
192+ watchTriggeredTasks . push ( plBuild ) ;
193+ gulp . watch ( src , gulp . series ( watchTriggeredTasks ) ) ;
194+ } ) ;
195+
196+ tasks . watch . push ( 'watch:pl' ) ;
197+ tasks . compile . push ( 'pl:full' ) ;
198+ } ;
0 commit comments