From 76c731fef9a1f27a56ff17b0e130788a828d6a52 Mon Sep 17 00:00:00 2001 From: Livii Iabanzhi Date: Mon, 18 Jun 2018 14:19:34 +0300 Subject: [PATCH 1/3] [WIP]Add directory support for --ignore-watch --- lib/API.js | 10 ++++++++++ lib/API/Modules/flagWatch.js | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 lib/API/Modules/flagWatch.js diff --git a/lib/API.js b/lib/API.js index 8424ef79a..2519691f3 100644 --- a/lib/API.js +++ b/lib/API.js @@ -23,6 +23,7 @@ var Modularizer = require('./API/Modules/Modularizer.js'); var path_structure = require('../paths.js'); var UX = require('./API/CliUx'); var pkg = require('../package.json'); +var flagWatch = require("./API/Modules/flagWatch.js"); var IMMUTABLE_MSG = chalk.bold.blue('Use --update-env to update environment variables'); @@ -623,6 +624,8 @@ class API { var app_conf = Config.transCMDToConf(opts); var appConf = {}; + var ignoreFileArray = []; + if (!!opts.executeCommand) app_conf.exec_mode = 'fork'; else if (opts.instances !== undefined) @@ -649,6 +652,13 @@ class API { app_conf = appConf[0]; + if (opts.ignoreWatch) { + flagWatch.handleFolders(opts.ignoreWatch, ignoreFileArray); + if (app_conf.ignore_watch) { + app_conf.ignore_watch = ignoreFileArray; + } + } + /** * If -w option, write configuration to configuration.json file */ diff --git a/lib/API/Modules/flagWatch.js b/lib/API/Modules/flagWatch.js new file mode 100644 index 000000000..6f8041c11 --- /dev/null +++ b/lib/API/Modules/flagWatch.js @@ -0,0 +1,20 @@ +var fs = require('fs'); + +function handleFolders(folder, mas) +{ + if (fs.lstatSync(folder) && fs.lstatSync(folder).isDirectory()) + { + fs.readdirSync(folder).forEach(file => { + if(fs.existsSync(folder + file + '/')) + handleFolders(folder + file + '/', mas); + else + mas.push(folder + file); + }); + } else { + if (fs.lstatSync(folder).isFile()) { + mas.push(folder); + } + } +} + +module.exports.handleFolders = handleFolders; From cae63134199dfc0204b43ed74594625aabfb5687 Mon Sep 17 00:00:00 2001 From: Livii Iabanzhi Date: Fri, 22 Jun 2018 18:00:09 +0300 Subject: [PATCH 2/3] Fixed --ignore-watch flag and written tests for --ignore-watch --- lib/API/Modules/flagWatch.js | 21 ++++++++--- test/programmatic/flagWatch.mocha.js | 55 ++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 test/programmatic/flagWatch.mocha.js diff --git a/lib/API/Modules/flagWatch.js b/lib/API/Modules/flagWatch.js index 6f8041c11..8603c9a63 100644 --- a/lib/API/Modules/flagWatch.js +++ b/lib/API/Modules/flagWatch.js @@ -1,17 +1,26 @@ var fs = require('fs'); -function handleFolders(folder, mas) -{ - if (fs.lstatSync(folder) && fs.lstatSync(folder).isDirectory()) - { +function handleFolders(folder, mas) { + if (!folder || !mas || folder.indexOf("node_modules") !== -1) + return ; + + try { + fs.accessSync(folder, fs.constants.R_OK); + } catch (err) { + return ; + } + + if (fs.statSync(folder) && fs.statSync(folder).isDirectory()) { fs.readdirSync(folder).forEach(file => { - if(fs.existsSync(folder + file + '/')) + if (fs.statSync(folder)["mode"] & 4 === 0) + return ; + if (fs.existsSync(folder + file + '/')) handleFolders(folder + file + '/', mas); else mas.push(folder + file); }); } else { - if (fs.lstatSync(folder).isFile()) { + if (fs.statSync(folder).isFile()) { mas.push(folder); } } diff --git a/test/programmatic/flagWatch.mocha.js b/test/programmatic/flagWatch.mocha.js new file mode 100644 index 000000000..01447b2d3 --- /dev/null +++ b/test/programmatic/flagWatch.mocha.js @@ -0,0 +1,55 @@ + +var should = require('should'); +var f_w = require('../../lib/API/Modules/flagWatch.js'); +var fs = require('fs'); + +describe('Flag --ignore-watch', function() { + + it('should return not empty result', function() { + var res = []; + f_w.handleFolders('./', res); + should(res).be.not.empty(); + }); + it('should not crash', function() { + var res = [] + f_w.handleFolders(); + f_w.handleFolders(res); + f_w.handleFolders(''); + f_w.handleFolders('lsdldmcsdf/amfkdmfk'); + }); + it('should give different results', function() { + var tmp_res = []; + var res = []; + f_w.handleFolders('./lib', res); + f_w.handleFolders('./examples', tmp_res); + should(res).not.equal(tmp_res); + }); + it('should not crash in case, when no access for file or directory by permissions', function() { + var fileStream; + + if (!fs.existsSync("noAccessDir")) + fs.mkdirSync("noAccessDir", 0777); + if (!fs.existsSync("noAccessDir/checkPermissions.txt")) { + fileStream = fs.createWriteStream("noAccessDir/checkPermissions.txt"); + fileStream.write("It's a temporary file for testing flag --ignore-watch in PM2"); + fileStream.end(); + } + fs.chmodSync('noAccessDir/checkPermissions.txt', 0000); + fs.chmodSync('noAccessDir', 0000); + + after(function () { + fs.chmodSync('noAccessDir', 0777); + fs.chmodSync('noAccessDir/checkPermissions.txt', 0777); + fs.unlinkSync('noAccessDir/checkPermissions.txt'); + fs.rmdirSync('noAccessDir/'); + }); + + f_w.handleFolders('noAccessDir/', []); + f_w.handleFolders('noAccessDir/checkPermissions.txt', []); + }); + it('should ignore node_modules folder', function() { + var res = []; + f_w.handleFolders('./node_modules', res); + should(res).be.empty(); + }); +}); \ No newline at end of file From 3785d6e50730f4969433b4e4d403b236d1e2707a Mon Sep 17 00:00:00 2001 From: Livii Iabanzhi Date: Fri, 22 Jun 2018 18:02:15 +0300 Subject: [PATCH 3/3] Implemented flag --watch-delay with tests --- bin/pm2 | 1 + lib/API.js | 8 ++++++++ lib/Watcher.js | 22 ++++++++++++---------- test/programmatic/flagWatch.mocha.js | 2 +- test/programmatic/watcher.js | 10 ++++++++++ 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/bin/pm2 b/bin/pm2 index 002657e7e..1c98b9d94 100755 --- a/bin/pm2 +++ b/bin/pm2 @@ -75,6 +75,7 @@ commander.version(pkg.version) .option('--merge-logs', 'merge logs from different instances but keep error and out separated') .option('--watch [paths]', 'watch application folder for changes', function(v, m) { m.push(v); return m;}, []) .option('--ignore-watch ', 'List of paths to ignore (name or regex)') + .option('--watch-delay ', 'specify a restart delay after changing files (--watch-delay 4 (in sec) or 4000ms)') .option('--no-color', 'skip colors') .option('--no-vizion', 'start an app without vizion feature (versioning control)') .option('--no-autorestart', 'start an app without automatic restart') diff --git a/lib/API.js b/lib/API.js index 2519691f3..e9f014482 100644 --- a/lib/API.js +++ b/lib/API.js @@ -659,6 +659,14 @@ class API { } } + if (opts.watchDelay) { + if (typeof opts.watchDelay === "string" && opts.watchDelay.indexOf("ms") !== -1) + app_conf.watch_delay = parseInt(opts.watchDelay); + else { + app_conf.watch_delay = parseFloat(opts.watchDelay) * 1000; + } + } + /** * If -w option, write configuration to configuration.json file */ diff --git a/lib/Watcher.js b/lib/Watcher.js index 1397d9308..5f499f26d 100644 --- a/lib/Watcher.js +++ b/lib/Watcher.js @@ -64,16 +64,18 @@ module.exports = function ClusterMode(God) { console.error('Change detected on path %s for app %s - restarting', path, pm2_env.name); - God.restartProcessName(pm2_env.name, function(err, list) { - self.restarting = false; - - if (err) { - log('Error while restarting', err); - return false; - } - - return log('Process restarted'); - }); + setTimeout(function() { + God.restartProcessName(pm2_env.name, function(err, list) { + self.restarting = false; + + if (err) { + log('Error while restarting', err); + return false; + } + + return log('Process restarted'); + }); + }, (pm2_env.watch_delay || 0)); return false; }); diff --git a/test/programmatic/flagWatch.mocha.js b/test/programmatic/flagWatch.mocha.js index 01447b2d3..572000bcc 100644 --- a/test/programmatic/flagWatch.mocha.js +++ b/test/programmatic/flagWatch.mocha.js @@ -52,4 +52,4 @@ describe('Flag --ignore-watch', function() { f_w.handleFolders('./node_modules', res); should(res).be.empty(); }); -}); \ No newline at end of file +}); diff --git a/test/programmatic/watcher.js b/test/programmatic/watcher.js index c0e172728..41d96e634 100644 --- a/test/programmatic/watcher.js +++ b/test/programmatic/watcher.js @@ -178,6 +178,16 @@ describe('Watcher', function() { }) }) + it('should work with watch_delay', function(cb) { + testPM2Env('server-watch:online')({watch: true, watch_delay: 4000}, cb); + pm2.start(extend(json, {watch: true, watch_delay: 4000}), errShouldBeNull); + }) + + it('should not crash with watch_delay without watch', function(cb) { + testPM2Env('server-watch:online')({watch_delay: 4000}, cb); + pm2.start(extend(json, {watch_delay: 4000}), errShouldBeNull); + }) + /** * Test #1668 */