'use strict'; var async = require('async'); var fork = require('child_process').fork; var env = process.env; var worker; var updateWorker; var initWorker; var incomplete = []; var running = 0; env.NODE_ENV = env.NODE_ENV || 'development'; var nconf = require('nconf'); nconf.file({ file: 'config.json', }); nconf.defaults({ base_dir: __dirname, views_dir: './build/public/templates', }); var winston = require('winston'); winston.configure({ transports: [ new winston.transports.Console({ handleExceptions: true, }), ], }); var db = require('./src/database'); module.exports = function (grunt) { var args = []; var initArgs = ['--build']; if (!grunt.option('verbose')) { args.push('--log-level=info'); initArgs.push('--log-level=info'); } function update(action, filepath, target) { var updateArgs = args.slice(); var compiling; var time = Date.now(); if (target === 'lessUpdated_Client') { compiling = 'clientCSS'; } else if (target === 'lessUpdated_Admin') { compiling = 'acpCSS'; } else if (target === 'clientUpdated') { compiling = 'js'; } else if (target === 'templatesUpdated') { compiling = 'tpl'; } else if (target === 'langUpdated') { compiling = 'lang'; } else if (target === 'serverUpdated') { // Do nothing, just restart } if (compiling && !incomplete.includes(compiling)) { incomplete.push(compiling); } updateArgs.push('--build'); updateArgs.push(incomplete.join(',')); worker.kill(); if (updateWorker) { updateWorker.kill('SIGKILL'); } updateWorker = fork('app.js', updateArgs, { env: env }); running += 1; updateWorker.on('exit', function () { running -= 1; if (running === 0) { worker = fork('app.js', args, { env: env, }); worker.on('message', function () { if (incomplete.length) { incomplete = []; if (grunt.option('verbose')) { grunt.log.writeln('NodeBB restarted in ' + (Date.now() - time) + ' ms'); } } }); } }); } grunt.initConfig({ watch: {}, }); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('default', ['watch']); grunt.registerTask('init', function () { var done = this.async(); async.waterfall([ function (next) { db.init(next); }, function (next) { db.getSortedSetRange('plugins:active', 0, -1, next); }, function (plugins, next) { addBaseThemes(plugins, next); }, function (plugins, next) { if (!plugins.includes('nodebb-plugin-composer-default')) { plugins.push('nodebb-plugin-composer-default'); } if (process.argv.includes('--core')) { plugins = []; } const lessUpdated_Client = plugins.map(p => 'node_modules/' + p + '/**/*.less'); const lessUpdated_Admin = plugins.map(p => 'node_modules/' + p + '/**/*.less'); const clientUpdated = plugins.map(p => 'node_modules/' + p + '/**/*.js'); const templatesUpdated = plugins.map(p => 'node_modules/' + p + '/**/*.tpl'); const langUpdated = plugins.map(p => 'node_modules/' + p + '/**/*.json'); grunt.config(['watch'], { lessUpdated_Client: { files: [ 'public/less/*.less', '!public/less/admin/**/*.less', ...lessUpdated_Client, '!node_modules/nodebb-*/node_modules/**', '!node_modules/nodebb-*/.git/**', ], options: { interval: 1000, }, }, lessUpdated_Admin: { files: [ 'public/less/admin/**/*.less', ...lessUpdated_Admin, '!node_modules/nodebb-*/node_modules/**', '!node_modules/nodebb-*/.git/**', ], options: { interval: 1000, }, }, clientUpdated: { files: [ 'public/src/**/*.js', ...clientUpdated, '!node_modules/nodebb-*/node_modules/**', 'node_modules/benchpressjs/build/benchpress.js', '!node_modules/nodebb-*/.git/**', ], options: { interval: 1000, }, }, serverUpdated: { files: ['*.js', 'install/*.js', 'src/**/*.js', '!src/upgrades/**'], options: { interval: 1000, }, }, templatesUpdated: { files: [ 'src/views/**/*.tpl', ...templatesUpdated, '!node_modules/nodebb-*/node_modules/**', '!node_modules/nodebb-*/.git/**', ], options: { interval: 1000, }, }, langUpdated: { files: [ 'public/language/en-GB/*.json', 'public/language/en-GB/**/*.json', ...langUpdated, '!node_modules/nodebb-*/node_modules/**', '!node_modules/nodebb-*/.git/**', '!node_modules/nodebb-*/plugin.json', '!node_modules/nodebb-*/package.json', '!node_modules/nodebb-*/theme.json', ], options: { interval: 1000, }, }, }); next(); }, ], done); }); grunt.task.run('init'); env.NODE_ENV = 'development'; if (grunt.option('skip')) { worker = fork('app.js', args, { env: env, }); } else { initWorker = fork('app.js', initArgs, { env: env, }); initWorker.on('exit', function () { worker = fork('app.js', args, { env: env, }); }); } grunt.event.on('watch', update); }; function addBaseThemes(plugins, callback) { const themeId = plugins.find(p => p.startsWith('nodebb-theme-')); if (!themeId) { return setImmediate(callback, null, plugins); } function getBaseRecursive(themeId) { try { const baseTheme = require(themeId + '/theme').baseTheme; if (baseTheme) { plugins.push(baseTheme); getBaseRecursive(baseTheme); } } catch (err) { console.log(err); } } getBaseRecursive(themeId); callback(null, plugins); }