Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / ot-br-posix / repo / third_party / mdl / repo / gulpfile.babel.js
1 /**
2  *
3  *  Material Design Lite
4  *  Copyright 2015 Google Inc. All rights reserved.
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      https://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  *
18  */
19
20 // jscs:disable jsDoc
21
22 'use strict';
23
24 // Include Gulp & Tools We'll Use
25 import fs from 'fs';
26 import path from 'path';
27 import mergeStream from 'merge-stream';
28 import del from 'del';
29 import vinylPaths from 'vinyl-paths';
30 import runSequence from 'run-sequence';
31 import browserSync from 'browser-sync';
32 import through from 'through2';
33 import swig from 'swig';
34 import gulp from 'gulp';
35 import closureCompiler from 'gulp-closure-compiler';
36 import gulpLoadPlugins from 'gulp-load-plugins';
37 import uniffe from './utils/uniffe.js';
38 import pkg from './package.json';
39
40 const $ = gulpLoadPlugins();
41 const reload = browserSync.reload;
42 const hostedLibsUrlPrefix = 'https://code.getmdl.io';
43 const templateArchivePrefix = 'mdl-template-';
44 const bucketProd = 'gs://www.getmdl.io';
45 const bucketStaging = 'gs://mdl-staging';
46 const bucketCode = 'gs://code.getmdl.io';
47 const banner = ['/**',
48   ' * <%= pkg.name %> - <%= pkg.description %>',
49   ' * @version v<%= pkg.version %>',
50   ' * @license <%= pkg.license %>',
51   ' * @copyright 2015 Google, Inc.',
52   ' * @link https://github.com/google/material-design-lite',
53   ' */',
54   ''].join('\n');
55
56 let codeFiles = '';
57
58 const AUTOPREFIXER_BROWSERS = [
59   'ie >= 10',
60   'ie_mob >= 10',
61   'ff >= 30',
62   'chrome >= 34',
63   'safari >= 7',
64   'opera >= 23',
65   'ios >= 7',
66   'android >= 4.4',
67   'bb >= 10'
68 ];
69
70 const SOURCES = [
71   // Component handler
72   'src/mdlComponentHandler.js',
73   // Polyfills/dependencies
74   'src/third_party/**/*.js',
75   // Base components
76   'src/button/button.js',
77   'src/checkbox/checkbox.js',
78   'src/icon-toggle/icon-toggle.js',
79   'src/menu/menu.js',
80   'src/progress/progress.js',
81   'src/radio/radio.js',
82   'src/slider/slider.js',
83   'src/snackbar/snackbar.js',
84   'src/spinner/spinner.js',
85   'src/switch/switch.js',
86   'src/tabs/tabs.js',
87   'src/textfield/textfield.js',
88   'src/tooltip/tooltip.js',
89   // Complex components (which reuse base components)
90   'src/layout/layout.js',
91   'src/data-table/data-table.js',
92   // And finally, the ripples
93   'src/ripple/ripple.js'
94 ];
95
96 // ***** Development tasks ****** //
97
98 // Lint JavaScript
99 gulp.task('lint', () => {
100   return gulp.src([
101       'src/**/*.js',
102       'gulpfile.babel.js'
103     ])
104     .pipe(reload({stream: true, once: true}))
105     .pipe($.jshint())
106     .pipe($.jscs())
107     .pipe($.jshint.reporter('jshint-stylish'))
108     .pipe($.jscs.reporter())
109     .pipe($.if(!browserSync.active, $.jshint.reporter('fail')))
110     .pipe($.if(!browserSync.active, $.jscs.reporter('fail')));
111 });
112
113 // ***** Production build tasks ****** //
114
115 // Optimize Images
116 // TODO: Update image paths in final CSS to match root/images
117 gulp.task('images', () => {
118   return gulp.src('src/**/*.{svg,png,jpg}')
119     .pipe($.flatten())
120     .pipe($.cache($.imagemin({
121       progressive: true,
122       interlaced: true
123     })))
124     .pipe(gulp.dest('dist/images'))
125     .pipe($.size({title: 'images'}));
126 });
127
128 // Compile and Automatically Prefix Stylesheets (dev)
129 gulp.task('styles:dev', () => {
130   return gulp.src('src/**/*.scss')
131     .pipe($.sass({
132       precision: 10,
133       onError: console.error.bind(console, 'Sass error:')
134     }))
135     .pipe($.cssInlineImages({
136       webRoot: 'src'
137     }))
138     .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
139     .pipe(gulp.dest('.tmp/styles'))
140     .pipe($.size({title: 'styles'}));
141 });
142
143 // Compile and Automatically Prefix Stylesheet Templates (production)
144 gulp.task('styletemplates', () => {
145   // For best performance, don't add Sass partials to `gulp.src`
146   return gulp.src('src/template.scss')
147     // Generate Source Maps
148     .pipe($.sourcemaps.init())
149     .pipe($.sass({
150       precision: 10,
151       onError: console.error.bind(console, 'Sass error:')
152     }))
153     .pipe($.cssInlineImages({webRoot: 'src'}))
154     .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
155     .pipe(gulp.dest('.tmp'))
156     // Concatenate Styles
157     .pipe($.concat('material.css.template'))
158     .pipe(gulp.dest('dist'))
159     // Minify Styles
160     .pipe($.if('*.css.template', $.csso()))
161     .pipe($.concat('material.min.css.template'))
162     .pipe($.header(banner, {pkg}))
163     .pipe($.sourcemaps.write('.'))
164     .pipe(gulp.dest('dist'))
165     .pipe($.size({title: 'styles'}));
166 });
167
168 // Compile and Automatically Prefix Stylesheets (production)
169 gulp.task('styles', () => {
170   // For best performance, don't add Sass partials to `gulp.src`
171   return gulp.src('src/material-design-lite.scss')
172     // Generate Source Maps
173     .pipe($.sourcemaps.init())
174     .pipe($.sass({
175       precision: 10,
176       onError: console.error.bind(console, 'Sass error:')
177     }))
178     .pipe($.cssInlineImages({webRoot: 'src'}))
179     .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
180     .pipe(gulp.dest('.tmp'))
181     // Concatenate Styles
182     .pipe($.concat('material.css'))
183     .pipe($.header(banner, {pkg}))
184     .pipe(gulp.dest('dist'))
185     // Minify Styles
186     .pipe($.if('*.css', $.csso()))
187     .pipe($.concat('material.min.css'))
188     .pipe($.header(banner, {pkg}))
189     .pipe($.sourcemaps.write('.'))
190     .pipe(gulp.dest('dist'))
191     .pipe($.size({title: 'styles'}));
192 });
193
194 // Only generate CSS styles for the MDL grid
195 gulp.task('styles-grid', () => {
196   return gulp.src('src/material-design-lite-grid.scss')
197     .pipe($.sass({
198       precision: 10,
199       onError: console.error.bind(console, 'Sass error:')
200     }))
201     .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
202     .pipe(gulp.dest('.tmp'))
203     // Concatenate Styles
204     .pipe($.concat('material-grid.css'))
205     .pipe($.header(banner, {pkg}))
206     .pipe(gulp.dest('dist'))
207     // Minify Styles
208     .pipe($.if('*.css', $.csso()))
209     .pipe($.concat('material-grid.min.css'))
210     .pipe($.header(banner, {pkg}))
211     .pipe(gulp.dest('dist'))
212     .pipe($.size({title: 'styles-grid'}));
213 });
214
215 // Build with Google's Closure Compiler, requires Java 1.7+ installed.
216 gulp.task('closure', () => {
217   return gulp.src(SOURCES)
218     .pipe(closureCompiler({
219       compilerPath: 'node_modules/google-closure-compiler/compiler.jar',
220       fileName: 'material.closure.min.js',
221       compilerFlags: {
222         // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
223         compilation_level: 'ADVANCED_OPTIMIZATIONS',
224         language_in: 'ECMASCRIPT6_STRICT',
225         language_out: 'ECMASCRIPT5_STRICT',
226         warning_level: 'VERBOSE'
227         // jscs:enable requireCamelCaseOrUpperCaseIdentifiers
228       }
229     }))
230     .pipe(gulp.dest('./dist'));
231 });
232
233 // Concatenate And Minify JavaScript
234 gulp.task('scripts', ['lint'], () => {
235   return gulp.src(SOURCES)
236     .pipe($.if(/mdlComponentHandler\.js/, $.util.noop(), uniffe()))
237     .pipe($.sourcemaps.init())
238     // Concatenate Scripts
239     .pipe($.concat('material.js'))
240     .pipe($.iife({useStrict: true}))
241     .pipe(gulp.dest('dist'))
242     // Minify Scripts
243     .pipe($.uglify({
244       sourceRoot: '.',
245       sourceMapIncludeSources: true
246     }))
247     .pipe($.header(banner, {pkg}))
248     .pipe($.concat('material.min.js'))
249     // Write Source Maps
250     .pipe($.sourcemaps.write('.'))
251     .pipe(gulp.dest('dist'))
252     .pipe($.size({title: 'scripts'}));
253 });
254
255 // Clean Output Directory
256 gulp.task('clean', () => del(['dist', '.publish']));
257
258 // Copy package manger and LICENSE files to dist
259 gulp.task('metadata', () => {
260   return gulp.src([
261       'package.json',
262       'bower.json',
263       'LICENSE'
264     ])
265     .pipe(gulp.dest('dist'));
266 });
267
268 // Build Production Files, the Default Task
269 gulp.task('default', ['clean'], cb => {
270   runSequence(
271     ['styles', 'styles-grid'],
272     ['scripts'],
273     ['mocha'],
274     cb);
275 });
276
277 // Build production files and microsite
278 gulp.task('all', ['clean'], cb => {
279   runSequence(
280     ['styletemplates'],
281     ['styles-grid', 'styles:gen'],
282     ['scripts'],
283     ['mocha'],
284     ['assets', 'pages',
285      'templates', 'images', 'metadata'],
286     ['zip'],
287     cb);
288 });
289
290 // ***** Testing tasks ***** //
291
292 gulp.task('mocha', ['styles'], () => {
293   return gulp.src('test/index.html')
294     .pipe($.mochaPhantomjs({reporter: 'tap'}));
295 });
296
297 gulp.task('mocha:closure', ['closure'], () => {
298   return gulp.src('test/index.html')
299     .pipe($.replace('src="../dist/material.js"',
300         'src="../dist/material.closure.min.js"'))
301     .pipe($.rename('temp.html'))
302     .pipe(gulp.dest('test'))
303     .pipe($.mochaPhantomjs({reporter: 'tap'}))
304     .on('finish', () => del.sync('test/temp.html'))
305     .on('error', () => del.sync('test/temp.html'));
306 });
307
308 gulp.task('test', [
309   'lint',
310   'mocha',
311   'mocha:closure'
312 ]);
313
314 gulp.task('test:visual', () => {
315   browserSync({
316     notify: false,
317     server: '.',
318     startPath: 'test/visual/index.html'
319   });
320
321   gulp.watch('test/visual/**', reload);
322 });
323
324 // ***** Landing page tasks ***** //
325
326 /**
327  * Site metadata for use with templates.
328  * @type {Object}
329  */
330 const site = {};
331
332 /**
333  * Generates an HTML file based on a template and file metadata.
334  */
335 function applyTemplate() {
336   return through.obj((file, enc, cb) => {
337     const data = {
338       site,
339       page: file.page,
340       content: file.contents.toString()
341     };
342
343     const templateFile = path.join(
344         __dirname, 'docs', '_templates', `${file.page.layout}.html`);
345     const tpl = swig.compileFile(templateFile, {cache: false});
346
347     file.contents = new Buffer(tpl(data));
348     cb(null, file);
349   });
350 }
351
352 /**
353  * Generates an index.html file for each README in MDL/src directory.
354  */
355 gulp.task('components', ['demos'], () => {
356   return gulp.src('src/**/README.md', {base: 'src'})
357     // Add basic front matter.
358     .pipe($.header('---\nlayout: component\nbodyclass: component\ninclude_prefix: ../../\n---\n\n'))
359     .pipe($.frontMatter({
360       property: 'page',
361       remove: true
362     }))
363     .pipe($.marked())
364     .pipe((() => {
365       return through.obj((file, enc, cb) => {
366         file.page.component = file.relative.split('/')[0];
367         cb(null, file);
368       });
369     })())
370     .pipe(applyTemplate())
371     .pipe($.rename(path => path.basename = 'index'))
372     .pipe(gulp.dest('dist/components'));
373 });
374
375 /**
376  * Copies demo files from MDL/src directory.
377  */
378 gulp.task('demoresources', () => {
379   return gulp.src([
380       'src/**/demos.css',
381       'src/**/demo.css',
382       'src/**/demo.js'
383     ], {base: 'src'})
384     .pipe($.if('*.scss', $.sass({
385       precision: 10,
386       onError: console.error.bind(console, 'Sass error:')
387     })))
388     .pipe($.cssInlineImages({webRoot: 'src'}))
389     .pipe($.if('*.css', $.autoprefixer(AUTOPREFIXER_BROWSERS)))
390     .pipe(gulp.dest('dist/components'));
391 });
392
393 /**
394  * Generates demo files for testing made of all the snippets and the demo file
395  * put together.
396  */
397 gulp.task('demos', ['demoresources'], () => {
398   /**
399    * Retrieves the list of component folders.
400    */
401   function getComponentFolders() {
402     return fs.readdirSync('src')
403       .filter(file => fs.statSync(path.join('src', file)).isDirectory());
404   }
405
406   const tasks = getComponentFolders().map(component => {
407     return gulp.src([
408         path.join('src', component, 'snippets', '*.html'),
409         path.join('src', component, 'demo.html')
410       ])
411       .pipe($.concat('/demo.html'))
412       // Add basic front matter.
413       .pipe($.header('---\nlayout: demo\nbodyclass: demo\ninclude_prefix: ../../\n---\n\n'))
414       .pipe($.frontMatter({
415         property: 'page',
416         remove: true
417       }))
418       .pipe($.marked())
419       .pipe((() => {
420         return through.obj((file, enc, cb) => {
421           file.page.component = component;
422           cb(null, file);
423         });
424       })())
425       .pipe(applyTemplate())
426       .pipe(gulp.dest(path.join('dist', 'components', component)));
427   });
428
429   return mergeStream(tasks);
430 });
431
432 /**
433  * Generates an HTML file for each md file in _pages directory.
434  */
435 gulp.task('pages', ['components'], () => {
436   return gulp.src('docs/_pages/*.md')
437     .pipe($.frontMatter({
438       property: 'page',
439       remove: true
440     }))
441     .pipe($.marked())
442     .pipe(applyTemplate())
443     .pipe($.replace('$$version$$', pkg.version))
444     .pipe($.replace('$$hosted_libs_prefix$$', hostedLibsUrlPrefix))
445     .pipe($.replace('$$template_archive_prefix$$', templateArchivePrefix))
446     /* Replacing code blocks class name to match Prism's. */
447     .pipe($.replace('class="lang-', 'class="language-'))
448     /* Translate html code blocks to "markup" because that's what Prism uses. */
449     .pipe($.replace('class="language-html', 'class="language-markup'))
450     .pipe($.rename(path => {
451       if (path.basename !== 'index') {
452         path.dirname = path.basename;
453         path.basename = 'index';
454       }
455     }))
456     .pipe(gulp.dest('dist'));
457 });
458
459 /**
460  * Copies assets from MDL and _assets directory.
461  */
462 gulp.task('assets', () => {
463   return gulp.src([
464       'docs/_assets/**/*',
465       'node_modules/clippy/build/clippy.swf',
466       'node_modules/swfobject-npm/swfobject/src/swfobject.js',
467       'node_modules/prismjs/prism.js',
468       'node_modules/prismjs/components/prism-markup.min.js',
469       'node_modules/prismjs/components/prism-javascript.min.js',
470       'node_modules/prismjs/components/prism-css.min.js',
471       'node_modules/prismjs/components/prism-bash.min.js',
472       'node_modules/prismjs/dist/prism-default/prism-default.css'
473     ])
474     .pipe($.if(/\.js/i, $.replace('$$version$$', pkg.version)))
475     .pipe($.if(/\.js/i, $.replace('$$hosted_libs_prefix$$', hostedLibsUrlPrefix)))
476     .pipe($.if(/\.(svg|jpg|png)$/i, $.imagemin({
477       progressive: true,
478       interlaced: true
479     })))
480     .pipe($.if(/\.css/i, $.autoprefixer(AUTOPREFIXER_BROWSERS)))
481     .pipe($.if(/\.css/i, $.csso()))
482     .pipe($.if(/\.js/i, $.uglify({
483       preserveComments: 'some',
484       sourceRoot: '.',
485       sourceMapIncludeSources: true
486     })))
487     .pipe(gulp.dest('dist/assets'));
488 });
489
490 /**
491  * Defines the list of resources to watch for changes.
492  */
493 function watch() {
494   gulp.watch(['src/**/*.js', '!src/**/README.md'],
495     ['scripts', 'demos', 'components', reload]);
496   gulp.watch(['src/**/*.{scss,css}'],
497     ['styles', 'styles-grid', 'styletemplates', reload]);
498   gulp.watch(['src/**/*.html'], ['pages', reload]);
499   gulp.watch(['src/**/*.{svg,png,jpg}'], ['images', reload]);
500   gulp.watch(['src/**/README.md'], ['pages', reload]);
501   gulp.watch(['templates/**/*'], ['templates', reload]);
502   gulp.watch(['docs/**/*'], ['pages', 'assets', reload]);
503   gulp.watch(['package.json', 'bower.json', 'LICENSE'], ['metadata']);
504 }
505
506 /**
507  * Serves the landing page from "out" directory.
508  */
509 gulp.task('serve:browsersync', () => {
510   browserSync({
511     notify: false,
512     server: {
513       baseDir: ['dist']
514     }
515   });
516
517   watch();
518 });
519
520 gulp.task('serve', () => {
521   $.connect.server({
522     root: 'dist',
523     port: 5000,
524     livereload: true
525   });
526
527   watch();
528
529   gulp.src('dist/index.html')
530     .pipe($.open({uri: 'http://localhost:5000'}));
531 });
532
533 // Generate release archive containing just JS, CSS, Source Map deps
534 gulp.task('zip:mdl', () => {
535   return gulp.src([
536       'dist/material?(.min)@(.js|.css)?(.map)',
537       'LICENSE',
538       'bower.json',
539       'package.json'
540     ])
541     .pipe($.zip('mdl.zip'))
542     .pipe(gulp.dest('dist'));
543 });
544
545 /**
546  * Returns the list of children directories inside the given directory.
547  * @param {string} dir the parent directory
548  * @return {Array<string>} list of child directories
549  */
550 function getSubDirectories(dir) {
551   return fs.readdirSync(dir)
552     .filter(file => fs.statSync(path.join(dir, file)).isDirectory());
553 }
554
555 // Generate release archives containing the templates and assets for templates.
556 gulp.task('zip:templates', () => {
557   const templates = getSubDirectories('dist/templates');
558
559   // Generate a zip file for each template.
560   const generateZips = templates.map(template => {
561     return gulp.src([
562         `dist/templates/${template}/**/*.*`,
563         'LICENSE'
564       ])
565       .pipe($.rename(path => {
566         path.dirname = path.dirname.replace(`dist/templates/${template}`, '');
567       }))
568       .pipe($.zip(`${templateArchivePrefix}${template}.zip`))
569       .pipe(gulp.dest('dist'));
570   });
571
572   return mergeStream(generateZips);
573 });
574
575 gulp.task('zip', [
576   'zip:templates',
577   'zip:mdl'
578 ]);
579
580 gulp.task('genCodeFiles', () => {
581   return gulp.src([
582       'dist/material.*@(js|css)?(.map)',
583       'dist/mdl.zip',
584       `dist/${templateArchivePrefix}*.zip`
585     ], {read: false})
586     .pipe($.tap(file => {
587       codeFiles += ` dist/${path.basename(file.path)}`;
588     }));
589 });
590
591 // Push the latest version of code resources (CSS+JS) to Google Cloud Storage.
592 // Public-read objects in GCS are served by a Google provided and supported
593 // global, high performance caching/content delivery network (CDN) service.
594 // This task requires gsutil to be installed and configured.
595 // For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
596 gulp.task('pushCodeFiles', () => {
597   const dest = bucketCode;
598   console.log(`Publishing ${pkg.version} to CDN (${dest})`);
599
600   // Build cache control and gsutil cmd to copy
601   // each object into a GCS bucket. The dest is a version specific path.
602   // The gsutil -m option requests parallel copies.
603   // The gsutil -h option is used to set metadata headers
604   // (cache control, in this case).
605   // Code files should NEVER be touched after uploading, therefore
606   // 30 days caching is a safe value.
607   const cacheControl = '-h "Cache-Control:public,max-age=2592000"';
608   const gsutilCpCmd = 'gsutil -m cp -z js,css,map ';
609   const gsutilCacheCmd = `gsutil -m setmeta -R ${cacheControl}`;
610
611   // Upload the goodies to a separate GCS bucket with versioning.
612   // Using a sep bucket avoids the risk of accidentally blowing away
613   // old versions in the microsite bucket.
614   return gulp.src('')
615     .pipe($.shell([
616       `${gsutilCpCmd}${codeFiles} ${dest}/${pkg.version}`,
617       `${gsutilCacheCmd} ${dest}/${pkg.version}`
618     ]));
619 });
620
621 gulp.task('publish:code', cb => {
622   runSequence(
623     ['zip:mdl', 'zip:templates'],
624     'genCodeFiles',
625     'pushCodeFiles',
626     cb);
627 });
628
629 /**
630  * Function to publish staging or prod version from local tree,
631  * or to promote staging to prod, per passed arg.
632  * @param {string} pubScope the scope to publish to.
633  */
634 function mdlPublish(pubScope) {
635   let cacheTtl = null;
636   let src = null;
637   let dest = null;
638
639   if (pubScope === 'staging') {
640     // Set staging specific vars here.
641     cacheTtl = 0;
642     src = 'dist/*';
643     dest = bucketStaging;
644   } else if (pubScope === 'prod') {
645     // Set prod specific vars here.
646     cacheTtl = 60;
647     src = 'dist/*';
648     dest = bucketProd;
649   } else if (pubScope === 'promote') {
650     // Set promote (essentially prod) specific vars here.
651     cacheTtl = 60;
652     src = `${bucketStaging}/*`;
653     dest = bucketProd;
654   }
655
656   let infoMsg = `Publishing ${pubScope}/${pkg.version} to GCS (${dest})`;
657   if (src) {
658     infoMsg += ` from ${src}`;
659   }
660   console.log(infoMsg);
661
662   // Build gsutil commands:
663   // The gsutil -h option is used to set metadata headers.
664   // The gsutil -m option requests parallel copies.
665   // The gsutil -R option is used for recursive file copy.
666   const cacheControl = `-h "Cache-Control:public,max-age=${cacheTtl}"`;
667   const gsutilCacheCmd = `gsutil -m setmeta ${cacheControl} ${dest}/**`;
668   const gsutilCpCmd = `gsutil -m cp -r -z html,css,js,svg ${src} ${dest}`;
669
670   gulp.src('').pipe($.shell([gsutilCpCmd, gsutilCacheCmd]));
671 }
672
673 // Push the local build of the MDL microsite and release artifacts to the
674 // production Google Cloud Storage bucket for general serving to the web.
675 // Public-read objects in GCS are served by a Google provided and supported
676 // global, high performance caching/content delivery network (CDN) service.
677 // This task requires gsutil to be installed and configured.
678 // For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
679 //
680 gulp.task('publish:prod', () => {
681   mdlPublish('prod');
682 });
683
684 // Promote the staging version of the MDL microsite and release artifacts
685 // to the production Google Cloud Storage bucket for general serving.
686 // Public-read objects in GCS are served by a Google provided and supported
687 // global, high performance caching/content delivery network (CDN) service.
688 // This task requires gsutil to be installed and configured.
689 // For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
690 //
691 gulp.task('publish:promote', () => {
692   mdlPublish('promote');
693 });
694
695 // Push the staged version of the MDL microsite and release artifacts
696 // to a production Google Cloud Storage bucket for staging and pre-production testing.
697 //
698 // This task requires gsutil to be installed and configured.
699 // For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
700 //
701 gulp.task('publish:staging', () => {
702   mdlPublish('staging');
703 });
704
705 gulp.task('_release', () => {
706   return gulp.src([
707       'dist/material?(.min)@(.js|.css)?(.map)',
708       'LICENSE',
709       'README.md',
710       'bower.json',
711       'package.json',
712       '.jscsrc',
713       '.jshintrc',
714       './sr?/**/*',
715       'gulpfile.babel.js',
716       './util?/**/*'
717     ])
718     .pipe(gulp.dest('_release'));
719 });
720
721 gulp.task('publish:release', ['_release'], () => {
722   return gulp.src('_release')
723     .pipe($.subtree({
724       remote: 'origin',
725       branch: 'release'
726     }))
727     .pipe(vinylPaths(del));
728 });
729
730 gulp.task('templates:styles', () => {
731   return gulp.src('templates/**/*.css')
732     .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
733     // FIXME: This crashes. It's a bug in gulp-csso,
734     // not csso itself.
735     //.pipe($.csso())
736     .pipe(gulp.dest('dist/templates'));
737 });
738
739 gulp.task('templates:static', () => {
740   return gulp.src('templates/**/*.html')
741   .pipe($.replace('$$version$$', pkg.version))
742   .pipe($.replace('$$hosted_libs_prefix$$', hostedLibsUrlPrefix))
743   .pipe(gulp.dest('dist/templates'));
744 });
745
746 // This task can be used if you want to test the templates against locally
747 // built version of the MDL libraries.
748 gulp.task('templates:localtestingoverride', () => {
749   return gulp.src('templates/**/*.html')
750     .pipe($.replace('$$version$$', '.'))
751     .pipe($.replace('$$hosted_libs_prefix$$', ''))
752     .pipe(gulp.dest('dist/templates'));
753 });
754
755 gulp.task('templates:images', () => {
756   return gulp.src('templates/*/images/**/*')
757     .pipe($.imagemin({
758       progressive: true,
759       interlaced: true
760     }))
761     .pipe(gulp.dest('dist/templates'));
762 });
763
764 gulp.task('templates:fonts', () => {
765   return gulp.src('templates/*/fonts/**/*')
766     .pipe(gulp.dest('dist/templates/'));
767 });
768
769 gulp.task('templates', [
770   'templates:static',
771   'templates:images',
772   'templates:fonts',
773   'templates:styles'
774 ]);
775
776 gulp.task('styles:gen', ['styles'], () => {
777   const MaterialCustomizer = require('./docs/_assets/customizer.js');
778   const templatePath = path.join(__dirname, 'dist', 'material.min.css.template');
779   // TODO: This task needs refactoring once we turn MaterialCustomizer
780   // into a proper Node module.
781   const mc = new MaterialCustomizer();
782   mc.template = fs.readFileSync(templatePath).toString();
783
784   let stream = gulp.src('');
785
786   mc.paletteIndices.forEach(primary => {
787     mc.paletteIndices.forEach(accent => {
788       if (primary === accent) {
789         return;
790       }
791
792       if (mc.forbiddenAccents.indexOf(accent) !== -1) {
793         return;
794       }
795
796       const primaryName = primary.toLowerCase().replace(' ', '_');
797       const accentName = accent.toLowerCase().replace(' ', '_');
798
799       stream = stream.pipe($.file(
800         `material.${primaryName}-${accentName}.min.css`,
801         mc.processTemplate(primary, accent)
802       ));
803     });
804   });
805
806   stream.pipe(gulp.dest('dist'));
807 });