k3s/www/master/gulpfile.js

518 lines
17 KiB
JavaScript

var gulp = require('gulp'), concat = require('gulp-concat'), uglify = require('gulp-uglify'),
// jade = require('gulp-jade'),
less = require('gulp-less'), path = require('path'),
livereload = require('gulp-livereload'), // Livereload plugin needed:
// https://chrome.google.com/webstore/detail/livereload/jnihajbhpnppcggbcgedagnkighmdlei
// marked = require('marked'), // For :markdown filter in jade
path = require('path'), changed = require('gulp-changed'), prettify = require('gulp-html-prettify'),
w3cjs = require('gulp-w3cjs'), rename = require('gulp-rename'),
// flip = require('css-flip'),
through = require('through2'), gutil = require('gulp-util'), htmlify = require('gulp-angular-htmlify'),
minifyCSS = require('gulp-minify-css'), gulpFilter = require('gulp-filter'), expect = require('gulp-expect-file'),
gulpsync = require('gulp-sync')(gulp), ngAnnotate = require('gulp-ng-annotate'),
sourcemaps = require('gulp-sourcemaps'), del = require('del'), jsoncombine = require('gulp-jsoncombine'),
ngConstant = require('gulp-ng-constant'), argv = require('yargs').argv, foreach = require('gulp-foreach'),
gcallback = require('gulp-callback'), changeCase = require('change-case'),
tag_version = require('gulp-tag-version'), PluginError = gutil.PluginError;
// LiveReload port. Change it only if there's a conflict
var lvr_port = 35729;
var W3C_OPTIONS = {
// Set here your local validator if your using one. leave it empty if not
// uri: 'http://validator/check',
doctype: 'HTML5',
output: 'json',
// Remove some messages that angular will always display.
filter: function(message) {
if (/Element head is missing a required instance of child element title/.test(message)) return false;
if (/Attribute .+ not allowed on element .+ at this point/.test(message)) return false;
if (/Element .+ not allowed as child of element .+ in this context/.test(message)) return false;
if (/Comments seen before doctype./.test(message)) return false;
}
};
// production mode (see build task)
var isProduction = false;
var useSourceMaps = false;
// ignore everything that begins with underscore
var hidden_files = '**/_*.*';
var ignored_files = '!' + hidden_files;
var component_hidden_files = '**/js/**/*.*';
var component_ignored_files = '!' + component_hidden_files;
// VENDOR CONFIG
var vendor = {
// vendor scripts required to start the app
base: {source: require('./vendor.base.json'), dest: '../app/assets/js', name: 'base.js'},
// vendor scripts to make to app work. Usually via lazy loading
app: {source: require('./vendor.json'), dest: '../app/vendor'}
};
// SOURCES CONFIG
var source = {
scripts: {
app: [
'js/app.preinit.js',
'js/app.init.js',
'js/app.config.js',
'js/app.directive.js',
'js/app.run.js',
'js/app.service.js',
'js/app.provider.js',
'js/tabs.js',
'js/sections.js',
'shared/config/generated-config.js',
'shared/js/modules/*.js',
'shared/js/modules/controllers/*.js',
'shared/js/modules/directives/*.js',
'shared/js/modules/services/*.js',
'components/*/js/**/*.js'
],
watch: ['manifest.json', 'js/**/*.js', 'shared/**/*.js', 'components/*/js/**/*.js']
},
// templates: {
// app: {
// files : ['jade/index.jade'],
// watch: ['jade/index.jade', hidden_files]
// },
// views: {
// files : ['jade/views/*.jade', 'jade/views/**/*.jade', ignored_files],
// watch: ['jade/views/**/*.jade']
// },
// pages: {
// files : ['jade/pages/*.jade'],
// watch: ['jade/pages/*.jade']
// }
// },
styles: {
app: {
// , 'components/*/less/*.less'
source: ['less/app/base.less', 'components/*/less/*.less'],
dir: ['less/app', 'components'],
watch: ['less/*.less', 'less/**/*.less', 'components/**/less/*.less', 'components/**/less/**/*.less']
}
},
components: {
source: [
'components/**/*.*',
component_ignored_files,
'!components/**/config/*.*',
'!master/shared/js/modules/config.js',
'!components/*/less/*.*',
'!components/**/less/**/*.*'
],
dest: 'components',
watch: [
'components/**/*.*',
component_ignored_files,
'!components/**/config/*.*',
'!master/shared/js/modules/config.js',
'!components/**/less/*.*'
]
},
config: {
watch: [
'shared/config/development.json',
'shared/config/production.json',
'shared/config/development.json',
'shared/config/production.json'
],
dest: 'shared/config'
},
assets: {source: ['shared/assets/**/*.*'], dest: 'shared/assets', watch: ['shared/assets/**/*.*']}
//,
// bootstrap: {
// main: 'less/bootstrap/bootstrap.less',
// dir: 'less/bootstrap',
// watch: ['less/bootstrap/*.less']
// }
};
// BUILD TARGET CONFIG
var build = {
scripts: {app: {main: 'app.js', dir: '../app/assets/js'}},
assets: '../app/shared/assets',
styles: '../app/assets/css',
components: {dir: '../app/components'}
};
function stringSrc(filename, string) {
var src = require('stream').Readable({objectMode: true});
src._read = function() {
this.push(new gutil.File({cwd: "", base: "", path: filename, contents: new Buffer(string)}));
this.push(null);
};
return src;
}
//---------------
// TASKS
//---------------
var manifestDirectory = function(manifestFile) {
return manifestFile.relative.slice(0, '/manifest.json'.length * -1);
};
gulp.task('bundle-manifest', function() {
var components = [];
var namespace = [];
gulp.src('./components/*/manifest.json')
.pipe(foreach (function(stream, file) {
var component = manifestDirectory(file);
components.push(component);
namespace.push(changeCase.camelCase(component));
return stream;
}))
.pipe(gcallback(function() {
var tabs = [];
components.forEach(function(component) {
tabs.push({component: component, title: changeCase.titleCase(component)});
});
stringSrc("tabs.js", 'app.value("tabs", ' + JSON.stringify(tabs) + ');').pipe(gulp.dest("js"));
var _appNS = 'kubernetesApp.components.';
var _appSkeleton = require('./js/app.skeleton.json');
stringSrc("app.preinit.js",
_appSkeleton.appSkeleton.replace('%s', '"' + _appNS + namespace.join('", "' + _appNS) + '"'))
.pipe(gulp.dest("js"));
}));
});
gulp.task('bundle-manifest-routes', function() {
var sections = [];
gulp.src('./components/*/manifest.json')
.pipe(foreach (function(stream, file) {
var component = manifestDirectory(file);
var manifestFile = require(file.path);
var routes = [];
if (manifestFile.routes) {
manifestFile.routes.forEach(function(r) {
// Hacky deep copy. Modifying manifestFile here will be repeated
// each time the task is called (consider watch/reload) due to
// cached file reads.
var route = JSON.parse(JSON.stringify(r));
if (route.url) {
route.url = '/' + component + route.url;
}
routes.push(route);
});
}
sections = sections.concat(routes);
return stream;
}))
.pipe(gcallback(function() {
var output_sections = JSON.stringify(sections);
var _file_contents = 'app.constant("manifestRoutes", ' + output_sections + ');\n';
stringSrc("sections.js", _file_contents).pipe(gulp.dest("js"));
}));
});
// JS APP
gulp.task('scripts:app', ['bundle-manifest', 'bundle-manifest-routes', 'config', 'scripts:app:base']);
// JS APP BUILD
gulp.task('scripts:app:base', function() {
// Minify and copy all JavaScript (except vendor scripts)
return gulp.src(source.scripts.app)
.pipe(useSourceMaps ? sourcemaps.init() : gutil.noop())
.pipe(concat(build.scripts.app.main))
.pipe(ngAnnotate())
.on("error", handleError)
.pipe(isProduction ? uglify({preserveComments: 'some'}) : gutil.noop())
.on("error", handleError)
.pipe(useSourceMaps ? sourcemaps.write() : gutil.noop())
.pipe(gulp.dest(build.scripts.app.dir));
});
// VENDOR BUILD
gulp.task('scripts:vendor', ['scripts:vendor:base', 'scripts:vendor:app']);
// This will be included vendor files statically
gulp.task('scripts:vendor:base', function() {
// Minify and copy all JavaScript (except vendor scripts)
return gulp.src(vendor.base.source)
.pipe(expect(vendor.base.source))
.pipe(uglify())
.pipe(concat(vendor.base.name))
.pipe(gulp.dest(vendor.base.dest));
});
// copy file from bower folder into the app vendor folder
gulp.task('scripts:vendor:app', function() {
var jsFilter = gulpFilter('**/*.js');
var cssFilter = gulpFilter('**/*.css');
return gulp.src(vendor.app.source, {base: 'bower_components'})
.pipe(expect(vendor.app.source))
.pipe(jsFilter)
.pipe(uglify())
.pipe(jsFilter.restore())
.pipe(cssFilter)
.pipe(minifyCSS())
.pipe(cssFilter.restore())
.pipe(gulp.dest(vendor.app.dest));
});
// APP LESS
gulp.task('styles:app', function() {
return gulp.src(source.styles.app.source)
.pipe(foreach (function(stream, file) { return stringSrc('import.less', '@import "' + file.relative + '";\n'); }))
.pipe(concat('app.less'))
.pipe(useSourceMaps ? sourcemaps.init() : gutil.noop())
.pipe(less({paths: source.styles.app.dir}))
.on("error", handleError)
.pipe(isProduction ? minifyCSS() : gutil.noop())
.pipe(useSourceMaps ? sourcemaps.write() : gutil.noop())
.pipe(gulp.dest(build.styles));
});
// // APP RTL
// gulp.task('styles:app:rtl', function() {
// return gulp.src(source.styles.app.main)
// .pipe( useSourceMaps ? sourcemaps.init() : gutil.noop())
// .pipe(less({
// paths: [source.styles.app.dir]
// }))
// .on("error", handleError)
// .pipe(flipcss())
// .pipe( isProduction ? minifyCSS() : gutil.noop() )
// .pipe( useSourceMaps ? sourcemaps.write() : gutil.noop())
// .pipe(rename(function(path) {
// path.basename += "-rtl";
// return path;
// }))
// .pipe(gulp.dest(build.styles));
// });
// Environment based configuration
// https://github.com/kubernetes-ui/kubernetes-ui/issues/21
gulp.task('config', ['config:base', 'config:copy']);
gulp.task('config:base', function() {
return stringSrc('generated-config.js', 'angular.module("kubernetesApp.config", [])' +
'\n' +
'.constant("ENV", {})').pipe(gulp.dest(source.config.dest));
});
gulp.task('config:copy', function() {
var environment = argv.env || 'development'; // change this to whatever default environment you need.
return gulp.src(['shared/config/' + environment + '.json', 'components/**/config/' + environment + '.json'])
.pipe(jsoncombine('generated-config.js',
function(data) {
var env = Object.keys(data).reduce(function(result, key) {
// Map the key "environment" to "/" and the keys "component/config/environment" to
// "component".
var newKey = key.replace(environment, '/').replace(/\/config\/\/$/, '');
result[newKey] = data[key];
return result;
}, {});
return new Buffer(JSON.stringify({'ENV': env}));
}))
.pipe(ngConstant({name: 'kubernetesApp.config', deps: [], constants: {ngConstant: true}}))
.pipe(gulp.dest(source.config.dest));
});
gulp.task('copy:components', function() {
var jsFilter = gulpFilter('**/*.js');
var cssFilter = gulpFilter('**/*.css');
del.sync([build.components.dir], {force: true});
return gulp.src(source.components.source, {base: 'components'})
.pipe(expect(source.components.source))
.pipe(jsFilter)
.pipe(uglify())
.pipe(jsFilter.restore())
.pipe(cssFilter)
.pipe(minifyCSS())
.pipe(cssFilter.restore())
.pipe(gulp.dest(build.components.dir));
});
gulp.task('copy:shared-assets', function() {
del.sync([build.assets], {force: true});
return gulp.src(source.assets.source, {base: 'shared/assets'})
.pipe(expect(source.assets.source))
.pipe(gulp.dest(build.assets));
});
// Assuming there's "version: 1.2.3" in package.json,
// tag the last commit as "v1.2.3"//
gulp.task('tag', function() { return gulp.src(['./package.json']).pipe(tag_version()); });
// // BOOSTRAP
// gulp.task('bootstrap', function() {
// return gulp.src(source.bootstrap.main)
// .pipe(less({
// paths: [source.bootstrap.dir]
// }))
// .on("error", handleError)
// .pipe(gulp.dest(build.styles));
// });
// JADE
// gulp.task('templates:app', function() {
// return gulp.src(source.templates.app.files)
// .pipe(changed(build.templates.app, { extension: '.html' }))
// .pipe(jade())
// .on("error", handleError)
// .pipe(prettify({
// indent_char: ' ',
// indent_size: 3,
// unformatted: ['a', 'sub', 'sup', 'b', 'i', 'u']
// }))
// // .pipe(htmlify({
// // customPrefixes: ['ui-']
// // }))
// // .pipe(w3cjs( W3C_OPTIONS ))
// .pipe(gulp.dest(build.templates.app))
// ;
// });
// // JADE
// gulp.task('templates:pages', function() {
// return gulp.src(source.templates.pages.files)
// .pipe(changed(build.templates.pages, { extension: '.html' }))
// .pipe(jade())
// .on("error", handleError)
// .pipe(prettify({
// indent_char: ' ',
// indent_size: 3,
// unformatted: ['a', 'sub', 'sup', 'b', 'i', 'u']
// }))
// // .pipe(htmlify({
// // customPrefixes: ['ui-']
// // }))
// // .pipe(w3cjs( W3C_OPTIONS ))
// .pipe(gulp.dest(build.templates.pages))
// ;
// });
// // JADE
// gulp.task('templates:views', function() {
// return gulp.src(source.templates.views.files)
// .pipe(changed(build.templates.views, { extension: '.html' }))
// .pipe(jade())
// .on("error", handleError)
// .pipe(prettify({
// indent_char: ' ',
// indent_size: 3,
// unformatted: ['a', 'sub', 'sup', 'b', 'i', 'u']
// }))
// // .pipe(htmlify({
// // customPrefixes: ['ui-']
// // }))
// // .pipe(w3cjs( W3C_OPTIONS ))
// .pipe(gulp.dest(build.templates.views))
// ;
// });
//---------------
// WATCH
//---------------
// Rerun the task when a file changes
gulp.task('watch', function() {
livereload.listen();
gulp.watch(source.scripts.watch, ['scripts:app']);
gulp.watch(source.styles.app.watch, ['styles:app']);
gulp.watch(source.components.watch, ['copy:components']);
gulp.watch(source.assets.watch, ['copy:shared-assets']);
// gulp.watch(source.templates.pages.watch, ['templates:pages']);
// gulp.watch(source.templates.views.watch, ['templates:views']);
// gulp.watch(source.templates.app.watch, ['templates:app']);
gulp.watch([
'../app/**'
])
.on('change', function(event) {
livereload.changed(event.path);
});
});
//---------------
// DEFAULT TASK
//---------------
// build for production (minify)
gulp.task('build', ['prod', 'default']);
gulp.task('prod', function() { isProduction = true; });
// build with sourcemaps (no minify)
gulp.task('sourcemaps', ['usesources', 'default']);
gulp.task('usesources', function() { useSourceMaps = true; });
// default (no minify)
gulp.task('default', gulpsync.sync(['scripts:vendor', 'copy:components', 'scripts:app', 'start']), function() {
gutil.log(gutil.colors.cyan('************'));
gutil.log(gutil.colors.cyan('* All Done *'),
'You can start editing your code, LiveReload will update your browser after any change..');
gutil.log(gutil.colors.cyan('************'));
});
gulp.task('start', [
'styles:app',
'copy:components',
'copy:shared-assets',
// 'templates:app',
// 'templates:pages',
// 'templates:views',
'watch'
]);
gulp.task('done', function() {
console.log('All Done!! You can start editing your code, LiveReload will update your browser after any change..');
});
// Error handler
function handleError(err) {
console.log(err.toString());
this.emit('end');
}
// // Mini gulp plugin to flip css (rtl)
// function flipcss(opt) {
// if (!opt) opt = {};
// // creating a stream through which each file will pass
// var stream = through.obj(function(file, enc, cb) {
// if(file.isNull()) return cb(null, file);
// if(file.isStream()) {
// console.log("todo: isStream!");
// }
// var flippedCss = flip(String(file.contents), opt);
// file.contents = new Buffer(flippedCss);
// cb(null, file);
// });
// // returning the file stream
// return stream;
// }