var gulp = require('gulp'); const jasmine = require('gulp-jasmine'); var gutil = require('gulp-util'); var wrap = require('gulp-wrap'); var concat = require('gulp-concat'); var merge = require('merge-stream'); var extend = require('gulp-extend'); var install = require('gulp-install'); var print = require('gulp-print'); var runSequence = require('run-sequence'); var del = require('del'); var fs = require('fs'); var webpack = require('webpack'); var WebpackDevServer = require('webpack-dev-server'); var exec = require('child_process').exec; // Configuration var srcDir = './client'; var buildDir = './services/nginx/static'; var langs = ['es', 'en']; var modules = require('./client/modules.json'); var webpackConfig = require('./webpack.config.js'); // Main tasks gulp.task('default', function() { return gulp.start('services', 'client'); }); gulp.task('build', ['clean'], function() { return gulp.start('routes', 'locales', 'webpack'); }); gulp.task('client', ['clean'], function() { return gulp.start('watch', 'routes', 'locales', 'webpack-dev-server'); }); gulp.task('nginxRestart', callback => { let isWindows = /^win/.test(process.platform); let command = isWindows ? './dev.cmd' : './dev.sh'; exec(command, (err, stdout, stderr) => { console.log(stdout); callback(err); }); }); gulp.task('services', () => { process.env.NODE_ENV = gutil.env.env || 'development'; const pathServices = './services/'; const services = fs.readdirSync(pathServices); services.splice(services.indexOf('loopback'), 1); return services.forEach(service => { const serviceJs = pathServices.concat(service, '/server/server.js'); if (fs.existsSync(serviceJs)) require(serviceJs).start(); }); }); gulp.task('clientDev', callback => { runSequence('nginxRestart', 'client', callback); }); gulp.task('servicesDev', callback => { let isWindows = /^win/.test(process.platform); let command = isWindows ? 'docker inspect dblocal | findstr Status' : 'docker inspect dblocal | grep Status'; gutil.env.env = 'test'; exec(command, (err, stdout, stderr) => { let isNotRunning = !stdout.includes('running'); if (isNotRunning) { runSequence('docker', 'waitForMySQL', 'services'); } else { runSequence('services'); } callback(err); }); }); gulp.task('clean', function() { return del([`${buildDir}/*`, `!${buildDir}/templates`, `!${buildDir}/images`], {force: true}); }); gulp.task('install', () => { const pathServices = './services/'; const fileJson = []; const services = fs.readdirSync(pathServices); services.push('..'); services.forEach(service => { fileJson.push(pathServices.concat(service, '/package.json')); }); return gulp.src(fileJson) .pipe(print(filepath => { return `Installing packages in ${filepath}`; })) .pipe(install({ npm: ['--no-package-lock'] })); }); // Webpack gulp.task('webpack', function(cb) { var configCopy = Object.create(webpackConfig); var compiler = webpack(configCopy); compiler.run(function(err, stats) { if (err) throw new gutil.PluginError('webpack', err); gutil.log('[webpack]', stats.toString({colors: true})); cb(); }); }); gulp.task('webpack-dev-server', function() { var configCopy = Object.create(webpackConfig); for (var entry in configCopy.entry) { configCopy.entry[entry] .unshift('webpack-dev-server/client?http://127.0.0.1:8081/'); } var compiler = webpack(configCopy); new WebpackDevServer(compiler, { publicPath: '/', contentBase: buildDir, quiet: false, noInfo: false, // hot: true, stats: { assets: true, colors: true, version: false, hash: false, timings: true, chunks: false, chunkModules: false } }).listen(8081, '127.0.0.1', function(err) { if (err) throw new gutil.PluginError('webpack-dev-server', err); }); }); // Locale var localeFiles = `${srcDir}/**/locale/*.json`; gulp.task('locales', function() { var streams = []; for (var mod in modules) for (var lang of langs) { var localeFiles = `./client/${mod}/**/locale/${lang}.json`; streams.push(gulp.src(localeFiles) .pipe(extend(`${lang}.json`)) .pipe(gulp.dest(`${buildDir}/locale/${mod}`))); } return merge(streams); }); // Routes var routeFiles = `${srcDir}/**/routes.json`; gulp.task('routes', function() { return gulp.src(routeFiles) .pipe(concat('routes.js', {newLine: ','})) .pipe(wrap('var routes = [<%=contents%>\n];')) .pipe(gulp.dest(buildDir)); }); // Watch gulp.task('watch', function() { gulp.watch(routeFiles, ['routes']); gulp.watch(localeFiles, ['locales']); }); // Server side unit tests gulp.task('test', callback => { return require('./services_tests').start(); }); // e2e tests gulp.task('e2e', callback => { runSequence('docker', 'waitForMySQL', 'endToEndTests', callback); }); gulp.task('waitForMySQL', callback => { let maxInterval = 30000; let interval = 1000; let timer = 0; console.log('Waiting for MySQL init process...'); let waitForLocaldb = setInterval(() => { if (timer < maxInterval) { timer += interval; exec('docker logs --tail 4 dblocal', (err, stdout, stderr) => { if (stdout.includes('MySQL init process done. Ready for start up.')) { clearInterval(waitForLocaldb); callback(err); } }); } else { console.log(`MySQL connection not established whithin ${maxInterval / 1000} secs!`); clearInterval(waitForLocaldb); } }, interval); }); gulp.task('endToEndTests', callback => { gulp.src('./e2e_tests.js') .pipe(jasmine({reporter: 'none'})); }); // docker dblocal gulp.task('docker', callback => { runSequence('deleteDockerDb', 'deleteDockerImageDb', 'buildDockerDb', 'runDockerDb', callback); }); gulp.task('runDockerDb', callback => { exec('docker run -d --name dblocal -p 3306:3306 dblocal', (err, stdout, stderr) => { setTimeout(() => { callback(err); }, 15000); }); }); gulp.task('buildDockerDb', callback => { exec('docker build -t dblocal:latest ./services/db', (err, stdout, stderr) => { callback(err); }); }); gulp.task('deleteDockerImageDb', callback => { exec('docker rmi dblocal:latest', (err, stdout, stderr) => { callback(err = null); }); }); gulp.task('deleteDockerDb', callback => { exec('docker stop dblocal && docker wait dblocal && docker rm -f dblocal', (err, stdout, stderr) => { callback(err = null); }); });