mybuddy/gulpfile.js

411 lines
9.5 KiB
JavaScript

const gulp = require('gulp');
const concat = require('gulp-concat');
const del = require('del');
const es = require('child_process').execSync;
const flatten = require('gulp-flatten');
const fontello = require('gulp-fontello');
const pump = require('pump');
const removeSourcemaps = require('gulp-remove-sourcemaps');
const sass = require('gulp-sass')(require('sass'));
const sassGlob = require('gulp-sass-glob');
const styleLint = require('gulp-stylelint');
const spawn = require('child_process').spawn;
const config = require('./gulpfile.config.js');
/**
* Support functions for Gulp tasks.
*/
function _runInPipenv(command, cb) {
command.unshift('run');
command = command.concat(process.argv.splice(3));
spawn('pipenv', command, { stdio: 'inherit' }).on('exit', function (code) {
if (code) process.exit(code);
cb();
});
}
/**
* Deletes local static files.
*
* @returns {*}
*/
function clean() {
return del([
'**/static',
'static'
]);
}
/**
* Runs coverage operations.
*
* @param cb
*/
function coverage(cb) {
// Erase any previous coverage results.
es('pipenv run coverage erase', {stdio: 'inherit'});
// Run tests with coverage.
spawn(
'pipenv',
[
'run',
'coverage',
'run',
'manage.py',
'test',
'--settings=babybuddy.settings.test',
'--parallel',
'--exclude-tag',
'isolate'
],
{
stdio: 'inherit'
}
).on('exit', function(code) {
// Run isolated tests with coverage.
if (code === 0) {
try {
config.testsConfig.isolated.forEach(function (test_name) {
es(
'pipenv run coverage run manage.py test ' + test_name,
{stdio: 'inherit'}
);
})
} catch (error) {
console.error(error);
cb();
process.exit(1);
}
// Combine coverage results.
es('pipenv run coverage combine', {stdio: 'inherit'});
}
cb();
process.exit(code)
});
}
/**
* Builds the documentation site locally.
*
* @param cb
*/
function docsBuild(cb) {
_runInPipenv(['mkdocs', 'build'], cb);
}
/**
* Deploys the documentation site to GitHub Pages.
*
* @param cb
*/
function docsDeploy(cb) {
_runInPipenv(['mkdocs', 'gh-deploy'], cb);
}
/**
* Serves the documentation site, watching for changes.
*
* @param cb
*/
function docsWatch(cb) {
_runInPipenv(['mkdocs', 'serve'], cb);
}
/**
* Builds and copies "extra" static files to configured paths.
*
* @param cb
*/
function extras(cb) {
pump([
gulp.src(config.extrasConfig.fonts.files),
gulp.dest(config.extrasConfig.fonts.dest)
], cb);
pump([
gulp.src(config.extrasConfig.images.files),
flatten({ subPath: 3 }),
gulp.dest(config.extrasConfig.images.dest)
], cb);
pump([
gulp.src(config.extrasConfig.logo.files),
flatten({ subPath: 3 }),
gulp.dest(config.extrasConfig.logo.dest)
], cb);
pump([
gulp.src(config.extrasConfig.root.files),
gulp.dest(config.extrasConfig.root.dest)
], cb);
}
/**
* Runs Black formatting on Python code.
*
* @param cb
*/
function format(cb) {
_runInPipenv(['black', '.'], cb);
}
/**
* Runs linting on Python and SASS code.
*
* @param cb
*/
function lint(cb) {
_runInPipenv(['black', '.', '--check', '--diff', '--color'], cb);
pump([
gulp.src(config.watchConfig.stylesGlob),
styleLint({
reporters: [
{ formatter: 'string', console: true }
]
})
], cb);
}
/**
* Builds and copies JavaScript static files to configured paths.
*
* @param cb
*/
function scripts(cb) {
pump([
gulp.src(config.scriptsConfig.vendor),
removeSourcemaps(),
concat('vendor.js'),
gulp.dest(config.scriptsConfig.dest)
], cb);
pump([
gulp.src(config.scriptsConfig.graph),
removeSourcemaps(),
concat('graph.js'),
gulp.dest(config.scriptsConfig.dest)
], cb);
pump([
gulp.src(config.scriptsConfig.app),
removeSourcemaps(),
concat('app.js'),
gulp.dest(config.scriptsConfig.dest)
], cb);
pump([
gulp.src(config.scriptsConfig.tags_editor),
concat('tags_editor.js'),
gulp.dest(config.scriptsConfig.dest)
], cb);
}
/**
* Builds and copies CSS static files to configured paths.
*
* @param cb
*/
function styles(cb) {
pump([
gulp.src(config.stylesConfig.app),
sassGlob({ignorePaths: config.stylesConfig.ignore}),
sass().on('error', sass.logError),
concat('app.css'),
gulp.dest(config.stylesConfig.dest)
], cb);
}
/**
* Runs all tests _not_ tagged "isolate".
*
* @param cb
*/
function test(cb) {
let command = [
'run',
'python',
'manage.py',
'test',
'--settings=babybuddy.settings.test',
'--parallel',
'--exclude-tag',
'isolate'
];
command = command.concat(process.argv.splice(3));
spawn('pipenv', command, { stdio: 'inherit' }).on('exit', function(code) {
if (code === 0) {
// Run isolated tests.
config.testsConfig.isolated.forEach(function(test_name) {
try {
es('pipenv run python manage.py test ' + test_name, {stdio: 'inherit'});
} catch (error) {
console.error(error);
cb();
process.exit(1);
}
})
}
cb();
process.exit(code);
});
}
/**
* Updates glyphs font data from Fontello.
*/
function updateglyphs(cb) {
pump([
gulp.src(config.glyphFontConfig.configFile),
fontello({ assetsOnly: false }),
gulp.dest(config.glyphFontConfig.dest)
], cb);
}
/**
* Watches for changes in configured files.
*/
function watch() {
gulp.watch(config.watchConfig.scriptsGlob, scripts);
gulp.watch(config.watchConfig.stylesGlob, styles);
}
/**
* Django management command passthroughs.
*/
gulp.task('collectstatic', function(cb) {
let command = ['run', 'python', 'manage.py', 'collectstatic'];
/* Use base settings if no settings parameter is supplied. */
const parameters = process.argv.splice(3);
let noSettings = true;
for (let i = 0; i < parameters.length; i++) {
if (parameters[i].substring(0, 10) === '--settings') {
noSettings = false;
break;
}
}
if (noSettings) {
parameters.push('--settings=babybuddy.settings.base');
}
command = command.concat(parameters);
spawn('pipenv', command, { stdio: 'inherit' }).on('exit', cb);
});
gulp.task('compilemessages', function(cb) {
_runInPipenv(['python', 'manage.py', 'compilemessages'], cb);
});
gulp.task('createcachetable', function(cb) {
_runInPipenv(['python', 'manage.py', 'createcachetable'], cb);
});
gulp.task('fake', function(cb) {
_runInPipenv(['python', 'manage.py', 'fake'], cb);
});
gulp.task('migrate', function(cb) {
_runInPipenv(['python', 'manage.py', 'migrate'], cb);
});
gulp.task('makemessages', function(cb) {
_runInPipenv(['python', 'manage.py', 'makemessages'], cb);
});
gulp.task('makemigrations', function(cb) {
_runInPipenv(['python', 'manage.py', 'makemigrations'], cb);
});
gulp.task('reset', function(cb) {
_runInPipenv(['python', 'manage.py', 'reset', '--no-input'], cb);
});
gulp.task('runserver', function(cb) {
let command = ['run', 'python', 'manage.py', 'runserver'];
/**
* Process any parameters. Any arguments found here will be removed from
* the parameters list so other parameters continue to be passed to the
* command.
**/
const parameters = process.argv.splice(2);
for (let i = 0; i < parameters.length; i++) {
/* May be included because this is the default gulp command. */
if (parameters[i] === 'runserver') {
delete parameters[i];
}
/* "--ip" parameter to set the server IP address. */
else if (parameters[i] === '--ip') {
command.push(parameters[i+1]);
delete parameters[i];
delete parameters[i+1];
i++;
}
}
/* Add parameters to command, removing empty values. */
command = command.concat(parameters.filter(String));
spawn('pipenv', command, { stdio: 'inherit' }).on('exit', cb);
});
gulp.task('generateschema', function(cb) {
_runInPipenv([
'python',
'manage.py',
'generateschema',
'--title',
'Baby Buddy API',
'--file',
'openapi-schema.yml'
], cb);
});
/**
* Gulp commands.
*/
gulp.task('clean', clean);
gulp.task('coverage', coverage);
gulp.task('docs:build', docsBuild);
gulp.task('docs:deploy', docsDeploy);
gulp.task('docs:watch', docsWatch);
gulp.task('extras', extras);
gulp.task('format', format);
gulp.task('lint', lint);
gulp.task('scripts', scripts);
gulp.task('styles', styles);
gulp.task('test', test);
gulp.task('updateglyphs', updateglyphs);
gulp.task('watch', watch);
/**
* Gulp compound commands.
*/
gulp.task('build', gulp.parallel('extras', 'scripts', 'styles'));
gulp.task('updatestatic', gulp.series('lint', 'clean', 'build', 'collectstatic'));
gulp.task('default', gulp.series('build', gulp.parallel('watch', 'runserver')));