mirror of
https://github.com/SrIzan10/nodemon.git
synced 2026-05-01 10:55:09 +00:00
163 lines
4.2 KiB
JavaScript
Executable File
163 lines
4.2 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
var fs = require('fs'),
|
|
sys = require('sys'),
|
|
childProcess = require('child_process'),
|
|
path = require('path'),
|
|
spawn = childProcess.spawn,
|
|
meta = JSON.parse(fs.readFileSync(__dirname + '/package.json')),
|
|
exec = childProcess.exec,
|
|
flag = './.monitor',
|
|
nodeArgs = process.ARGV.splice(2), // removes 'node' and this script
|
|
app = nodeArgs[0],
|
|
node = null,
|
|
monitor = null,
|
|
ignoreFilePath = './nodemon-ignore',
|
|
ignoreFiles = [flag, ignoreFilePath], // ignore the monitor flag by default
|
|
reIgnoreFiles = null,
|
|
timeout = 1000, // check every 1 second
|
|
// create once, reuse as needed
|
|
reComments = /#.*$/,
|
|
reTrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
|
|
reEscapeChars = /[.|\-[\]()\\]/g,
|
|
reAsterisk = /\*/g;
|
|
|
|
function startNode() {
|
|
sys.log('\x1B[32m[nodemon] starting node\x1B[0m');
|
|
node = spawn('node', nodeArgs);
|
|
|
|
node.stdout.on('data', function (data) {
|
|
sys.print(data);
|
|
});
|
|
|
|
node.stderr.on('data', function (data) {
|
|
sys.error(data);
|
|
});
|
|
|
|
node.on('exit', function (code, signal) {
|
|
// exit the monitor, but do it gracefully
|
|
if (signal == 'SIGUSR2') {
|
|
// restart
|
|
startNode();
|
|
} else {
|
|
sys.log('\x1B[1;31m[nodemon] app crashed - waiting for file change before starting...\x1B[0m');
|
|
node = null;
|
|
}
|
|
});
|
|
}
|
|
|
|
function startMonitor() {
|
|
var cmd = 'find . -type f -newer ' + flag + ' -print';
|
|
|
|
exec(cmd, function (error, stdout, stderr) {
|
|
var files = stdout.split(/\n/);
|
|
|
|
files.pop(); // remove blank line ending and split
|
|
if (files.length) {
|
|
// filter ignored files
|
|
if (ignoreFiles.length) {
|
|
files = files.filter(function(file) {
|
|
return !reIgnoreFiles.test(file);
|
|
});
|
|
}
|
|
|
|
fs.writeFileSync(flag, '');
|
|
|
|
if (files.length) {
|
|
sys.log('[nodemon] restarting due to changes...');
|
|
files.forEach(function (file) {
|
|
sys.log('[nodemon] ' + file);
|
|
});
|
|
sys.print('\n\n');
|
|
|
|
if (node !== null) {
|
|
node.kill('SIGUSR2');
|
|
} else {
|
|
startNode();
|
|
}
|
|
}
|
|
}
|
|
|
|
setTimeout(startMonitor, timeout);
|
|
});
|
|
}
|
|
|
|
function readIgnoreFile() {
|
|
fs.unwatchFile(ignoreFilePath);
|
|
|
|
// Check if ignore file still exists. Vim tends to delete it before replacing with changed file
|
|
path.exists(ignoreFilePath, function(exists) {
|
|
if (!exists) {
|
|
// we'll touch the ignore file to make sure it gets created and
|
|
// if Vim is writing the file, it'll just overwrite it - but also
|
|
// prevent from constant file io if the file doesn't exist
|
|
fs.writeFileSync(ignoreFilePath, "\n");
|
|
setTimeout(readIgnoreFile, 500);
|
|
return;
|
|
}
|
|
|
|
sys.log('[nodemon] reading ignore list');
|
|
|
|
ignoreFiles = [flag, ignoreFilePath];
|
|
fs.readFileSync(ignoreFilePath).toString().split(/\n/).forEach(function (line) {
|
|
// remove comments and trim lines
|
|
if (line = line.replace(reComments, '').replace(reTrim, '')) {
|
|
ignoreFiles.push(line.replace(reEscapeChars, '\\$&').replace(reAsterisk, '.*'));
|
|
}
|
|
});
|
|
reIgnoreFiles = new RegExp(ignoreFiles.join('|'));
|
|
|
|
fs.watchFile(ignoreFilePath, { persistent: false }, readIgnoreFile);
|
|
});
|
|
}
|
|
|
|
function usage() {
|
|
sys.print('usage: nodemon [--debug] [your node app]\ne.g.: nodemon ./server.js localhost 8080\nFor details see http://github.com/remy/nodemon/\n\n');
|
|
}
|
|
|
|
if (!nodeArgs.length || nodeArgs[0] == 'help') {
|
|
usage();
|
|
process.exit(0);
|
|
}
|
|
|
|
if (nodeArgs[0] == 'version') {
|
|
sys.print('v' + meta.version + '\n');
|
|
process.exit(0);
|
|
}
|
|
|
|
|
|
if (nodeArgs[0] == '--debug') {
|
|
app = nodeArgs[1];
|
|
}
|
|
|
|
|
|
sys.log('[nodemon] v' + meta.version);
|
|
|
|
// Change to application dir
|
|
process.chdir(path.dirname(app));
|
|
app = path.basename(app);
|
|
sys.log('[nodemon] running ' + app + ' in ' + process.cwd());
|
|
|
|
startNode();
|
|
setTimeout(startMonitor, timeout);
|
|
|
|
path.exists(ignoreFilePath, readIgnoreFile);
|
|
|
|
// touch
|
|
fs.writeFileSync(flag, '');
|
|
|
|
// remove the flag file on exit
|
|
process.on('exit', function (code) {
|
|
sys.log('[nodemon] exiting');
|
|
fs.unlink(flag);
|
|
});
|
|
|
|
process.on('SIGINT', function () {
|
|
process.exit(0);
|
|
});
|
|
|
|
process.on('uncaughtException', function (err) {
|
|
sys.log('[nodemon] exception in nodemon killing node');
|
|
sys.error(err.stack);
|
|
node.kill();
|
|
});
|