#!/usr/bin/env node var program = require('commander'); var spawn = require('child_process').spawn; var chokidar = require('chokidar'); var fs = require('fs'); program .option('-s, --suite ', 'The suite to run Authelia for. This suite represents a configuration for Authelia and a set of tests for that configuration.') .parse(process.argv) if (!program.suite) { throw new Error('Please provide a suite.'); } const ENVIRONMENT_FILENAME = '.suite'; var tsWatcher = chokidar.watch(['server', 'shared/**/*.ts', 'node_modules'], { persistent: true, ignoreInitial: true, }); // Properly cleanup server and client if ctrl-c is hit process.on('SIGINT', function() { killServer(() => {}); killClient(() => {}); fs.unlinkSync(ENVIRONMENT_FILENAME); process.exit(); }); let serverProcess; function reloadServer() { killServer(() => { startServer(); }); } function startServer() { serverProcess = spawn('./scripts/run-dev-server.sh', [`test/suites/${program.suite}/config.yml`], {detached: true}); serverProcess.stdout.pipe(process.stdout); serverProcess.stderr.pipe(process.stderr); } let clientProcess; function startClient() { clientProcess = spawn('npm', ['run', 'start'], { detached: true, cwd: './client', env: { ...process.env, 'BROWSER': 'none' } }); clientProcess.stdout.pipe(process.stdout); clientProcess.stderr.pipe(process.stderr); } function killServer(onExit) { if (serverProcess) { serverProcess.on('exit', () => { serverProcess = undefined; onExit(); }); try { process.kill(-serverProcess.pid); } catch (e) { console.error(e); onExit(); } } } function killClient(onExit) { if (clientProcess) { clientProcess.on('exit', () => { clientProcess = undefined; onExit(); }); try { process.kill(-clientProcess.pid); } catch (e) { console.error(e); onExit(); } } } function generateConfigurationSchema() { exec('./node_modules/.bin/typescript-json-schema -o server/src/lib/configuration/Configuration.schema.json --strictNullChecks --required server/tsconfig.json Configuration'); } function reload(path) { console.log(`File ${path} has been changed, reloading...`); if (path.startsWith('server/src/lib/configuration/schema')) { console.log('Schema needs to be regenerated.'); generateConfigurationSchema(); } reloadServer(); } function exec(command, args) { return new Promise((resolve, reject) => { const cmd = spawn(command, args); cmd.stdout.pipe(process.stdout); cmd.stderr.pipe(process.stderr); cmd.on('close', (code) => { if (code == 0) { resolve(); return; } reject(new Error('Status code ' + code)); }); }); } async function main() { console.log(`Create suite file ${ENVIRONMENT_FILENAME}.`); fs.writeFileSync(ENVIRONMENT_FILENAME, program.suite); console.log(`Render nginx configuration...`); await exec('./example/compose/nginx/portal/render.js'); console.log(`Prepare environment with docker-compose...`); await exec('./scripts/utils/prepare-environment.sh'); console.log('Start watching...'); tsWatcher.on('add', reload); tsWatcher.on('remove', reload); tsWatcher.on('change', reload); startServer(); startClient(); } main()