UNPKG

simple-auto-deploy

Version:

Utility to auto-deploy a node app on another folder

121 lines (104 loc) 2.98 kB
const path = require('path'); const watch = require('node-watch'); const Rsync = require('rsync'); const Promise = require('bluebird'); const childProcess = require('child_process'); const touch = Promise.promisify(require('touch')); const DELAY_BEFORE_SYNC = 50; const DELAY_BEFORE_NPM_UPDATE = 200; module.exports = class { constructor(source, target) { if (!source || !target) { throw new Error('source and destination are required.'); } console.log(`SimpleDeploy "${source}" > "${target}"`); this.source = this._getAbsolutePath(source); this.target = this._getAbsolutePath(target); this.rsync = new Rsync() .flags('av') .exclude(['node_modules/', '.git/']) .delete() .source(path.join(this.source, path.sep)) .destination(this.target); this.rsync = Promise.promisifyAll(this.rsync); } _getAbsolutePath(pathString) { if (path.isAbsolute(pathString)) { return pathString; } return path.join(process.cwd(), pathString); } watch() { this._sync(); return watch(this.source, (action, file) => { console.log(action, file); this._sync(); }); } isProcessing() { return this._isProcessing; } isSynchronizing() { return this._isSynchronizing; } isUpdatingModules() { return this._isUpdatingModules; } _scheduleSync() { if (this._nextSync) { clearTimeout(this._nextSync); } this._nextSync = setTimeout(() => { this._nextSync = null; this._sync(); }, DELAY_BEFORE_SYNC); } _sync() { if (this.isProcessing()) { return this._scheduleSync(); } this._isProcessing = true; this._isSynchronizing = true; process.nextTick(() => { this.rsync.executeAsync().then(() => { this._scheduleUpdateModules(); this._isSynchronizing = false; }).catch((error) => { console.error(error); this._isSynchronizing = false; this._isProcessing = false; }); }); } _scheduleUpdateModules() { if (this._nextUpdateModules) { clearTimeout(this._nextUpdateModules); } this._nextUpdateModules = setTimeout(() => { this._updateModules(); }, DELAY_BEFORE_NPM_UPDATE); } _updateModules() { if (this.isSynchronizing() || this.isUpdatingModules()) { return this._scheduleUpdateModules(); } this._isUpdatingModules = true; process.nextTick(() => { this._spawn('yarn', ['install']).then(() => { return touch(path.join(this.target, 'simple-deploy-done')); }).then(() => { this._isUpdatingModules = false; this._isProcessing = false; }); }); } _spawn(command, args) { const options = {'cwd': this.target}; const child = childProcess.spawn(command, args, options); child.stdout.pipe(process.stdout); child.stderr.pipe(process.stderr); return new Promise((resolve) => { child.on('close', resolve); }); } };