Stairs/gulpfile.js

295 lines
6.5 KiB
JavaScript

/*
* Stairs
* Copyright 2017 (c) Mark van Renswoude
*
* https://git.x2software.net/pub/Stairs
*/
'use strict';
const gulp = require('gulp');
const htmlmin = require('gulp-htmlmin');
const cppstringify = require('./gulp-cppstringify');
const fs = require('fs');
const plumber = require('gulp-plumber');
const sass = require('gulp-sass');
const cleanCSS = require('gulp-clean-css');
const watch = require('gulp-debounced-watch');
const uglify = require('gulp-uglify');
const concat = require('gulp-concat');
const print = require('gulp-print');
const path = require('path');
const gzip = require('gulp-gzip');
const config = {
assetsPath: 'web/',
distPath: 'web/dist/',
outputPath: 'src/assets/',
firmwareArtifact: '.pioenvs/esp12e/firmware.bin',
firmwareOutputPath: 'bin/'
};
const HTMLMap = {
'index.html': 'Index'
};
const JSMap = {
'bundle.js': 'BundleJS'
};
const CSSMap = {
'bundle.css': 'BundleCSS'
};
// There is an issue in the AsyncWebServer where it's apparantly running
// out of memory on simultaneous requests. We'll work around it by
// merging all the JS into one big file.
//
// https://github.com/me-no-dev/ESPAsyncWebServer/issues/256
const JSSrc = [
'node_modules/axios/dist/axios.min.js',
'node_modules/vue/dist/vue.min.js',
'node_modules/vue-i18n/dist/vue-i18n.min.js',
'web/lang.js',
'web/app.js'
];
const SCSSSrc = [
'web/site.scss'
]
gulp.task('default',
[
'embedAssets'
],
function(){});
gulp.task('watch',
[
'compileScss',
'compileJS'
],
function()
{
watch(config.assetsPath + '*.scss', function() { gulp.start('compileScss'); });
watch(config.assetsPath + '*.js', function() { gulp.start('compileJS'); });
});
gulp.task('embedHTML', function()
{
return gulp.src(config.assetsPath + '*.html')
.pipe(print(function(filepath) { return 'HTML: ' + filepath }))
.pipe(htmlmin({
collapseWhitespace: true,
removeComments: true,
minifyCSS: true,
minifyJS: true
}))
.pipe(gzip({ append: false }))
.pipe(cppstringify('html.h', {
headerDefineName: '__assets_html',
map: HTMLMap,
byteArray: true
}))
.pipe(gulp.dest(config.outputPath));
});
gulp.task('compileScss', function()
{
return gulp.src(SCSSSrc)
.pipe(plumber({
errorHandler: function (error)
{
console.log(error.toString());
this.emit('end');
}}))
.pipe(print(function(filepath) { return 'SCSS: ' + filepath }))
.pipe(sass({
includePaths: ['node_modules/milligram/src']
}))
.pipe(cleanCSS({compatibility: 'ie9'}))
.pipe(concat('bundle.css'))
.pipe(gulp.dest(config.distPath));
});
gulp.task('compileJS', function()
{
return gulp.src(JSSrc)
.pipe(plumber({
errorHandler: function (error)
{
console.log(error.toString());
this.emit('end');
}}))
.pipe(print(function(filepath) { return 'JS: ' + filepath }))
.pipe(concat('bundle.js'))
.pipe(uglify())
.pipe(gulp.dest(config.distPath));
});
gulp.task('embedJS', ['compileJS'], function()
{
return gulp.src([config.distPath + 'bundle.js'])
.pipe(gzip({ append: false }))
.pipe(cppstringify('js.h', {
headerDefineName: '__assets_js',
map: JSMap,
byteArray: true
}))
.pipe(gulp.dest(config.outputPath));
});
gulp.task('embedCSS', ['compileScss'], function()
{
return gulp.src([config.distPath + 'bundle.css'])
.pipe(gzip({ append: false }))
.pipe(cppstringify('css.h', {
headerDefineName: '__embed_css',
map: CSSMap,
byteArray: true
}))
.pipe(gulp.dest(config.outputPath));
});
var version = false;
function getVersion(callback)
{
if (version !== false)
{
callback(version);
return;
}
var versionData = '';
const cmd = spawn('gitversion');
cmd.stdout.on('data', function(data)
{
versionData += data;
});
cmd.stderr.on('data', function(data)
{
console.log(data.toString().trim());
});
cmd.on('exit', function(code)
{
if (code != 0) return;
var version = JSON.parse(versionData);
callback(version);
});
}
gulp.task('embedVersion', function(cb)
{
getVersion(function(version)
{
var headerFile = "#ifndef __assets_version\r\n";
headerFile += "#define __assets_version\r\n\r\n";
headerFile += "const uint8_t VersionMajor = " + version.Major + ";\r\n";
headerFile += "const uint8_t VersionMinor = " + version.Minor + ";\r\n";
headerFile += "const uint8_t VersionPatch = " + version.Patch + ";\r\n";
headerFile += "const uint8_t VersionMetadata = " + (version.BuildMetaData ? version.BuildMetaData : '0') + ";\r\n";
headerFile += "const char VersionBranch[] = \"" + version.BranchName + "\";\r\n";
headerFile += "const char VersionSemVer[] = \"" + version.SemVer + "\";\r\n";
headerFile += "const char VersionFullSemVer[] = \"" + version.FullSemVer + "\";\r\n";
headerFile += "const char VersionCommitDate[] = \"" + version.CommitDate + "\";\r\n";
headerFile += "\r\n#endif\r\n";
fs.writeFile(config.outputPath + 'version.h', headerFile, function(err)
{
if (err) throw err;
cb();
});
});
});
gulp.task('copyBinary', function(cb)
{
if (!fs.existsSync(config.firmwareOutputPath))
fs.mkdirSync(config.firmwareOutputPath, '0777', true);
getVersion(function(version)
{
var target = path.join(config.firmwareOutputPath, version.FullSemVer + '.bin');
console.log('Target: ' + target);
var reader = fs.createReadStream(config.firmwareArtifact);
reader.pipe(fs.createWriteStream(target));
reader.on('end', cb);
});
});
gulp.task('embedAssets', ['embedHTML', 'embedJS', 'embedCSS', 'embedVersion'], function() { })
// PlatformIO
const spawn = require('child_process').spawn;
const argv = require('yargs').argv;
var platformio = function(target)
{
var args = ['run'];
if ("e" in argv)
{
args.push('-e');
args.push(argv.e);
}
if ("p" in argv)
{
args.push('--upload-port');
args.push(argv.p);
}
if (target)
{
args.push('-t');
args.push(target);
}
const cmd = spawn('platformio', args);
cmd.stdout.on('data', function(data)
{
console.log(data.toString().trim());
});
cmd.stderr.on('data', function(data)
{
console.log(data.toString().trim());
});
cmd.on('exit', function(code)
{
if (code != 0) return;
gulp.start('copyBinary');
});
}
gulp.task('upload', ['embedHTML', 'embedAssets'], function() { platformio('upload'); });
gulp.task('build', ['embedHTML', 'embedAssets'], function() { platformio(false); });