mirror of
https://github.com/SrIzan10/nodemon.git
synced 2026-05-01 10:55:09 +00:00
@@ -16,7 +16,7 @@ var restart = null;
|
||||
var psTree = require('pstree.remy');
|
||||
var path = require('path');
|
||||
var signals = require('./signals');
|
||||
const osRelease = parseInt(require('os').release().split(".")[0], 10);
|
||||
const osRelease = parseInt(require('os').release().split('.')[0], 10);
|
||||
|
||||
function run(options) {
|
||||
var cmd = config.command.raw;
|
||||
@@ -67,7 +67,7 @@ function run(options) {
|
||||
PATH: binPath + ':' + process.env.PATH,
|
||||
}),
|
||||
stdio: stdio,
|
||||
}
|
||||
};
|
||||
|
||||
var executable = cmd.executable;
|
||||
|
||||
@@ -76,12 +76,15 @@ function run(options) {
|
||||
// but *only* apply to the first command, and none of the arguments.
|
||||
// ref #1251 and #1236
|
||||
if (executable.indexOf('/') !== -1) {
|
||||
executable = executable.split(' ').map((e, i) => {
|
||||
if (i === 0) {
|
||||
return path.normalize(e);
|
||||
}
|
||||
return e;
|
||||
}).join(' ');
|
||||
executable = executable
|
||||
.split(' ')
|
||||
.map((e, i) => {
|
||||
if (i === 0) {
|
||||
return path.normalize(e);
|
||||
}
|
||||
return e;
|
||||
})
|
||||
.join(' ');
|
||||
}
|
||||
// taken from npm's cli: https://git.io/vNFD4
|
||||
sh = process.env.comspec || 'cmd';
|
||||
@@ -111,7 +114,7 @@ function run(options) {
|
||||
!(firstArg.indexOf('-') === 0) && // don't fork if there's a node exec arg
|
||||
firstArg !== 'inspect' && // don't fork it's `inspect` debugger
|
||||
executable === 'node' && // only fork if node
|
||||
utils.version.major > 4 // only fork if node version > 4
|
||||
utils.version.major > 4; // only fork if node version > 4
|
||||
|
||||
if (shouldFork) {
|
||||
// this assumes the first argument is the script and slices it out, since
|
||||
@@ -125,7 +128,7 @@ function run(options) {
|
||||
silent: !hasStdio,
|
||||
});
|
||||
utils.log.detail('forking');
|
||||
debug('fork', sh, shFlag, args)
|
||||
debug('fork', sh, shFlag, args);
|
||||
} else {
|
||||
utils.log.detail('spawning');
|
||||
child = spawn.apply(null, spawnArgs);
|
||||
@@ -181,8 +184,9 @@ function run(options) {
|
||||
}
|
||||
|
||||
if (code === 127) {
|
||||
utils.log.error('failed to start process, "' + cmd.executable +
|
||||
'" exec not found');
|
||||
utils.log.error(
|
||||
'failed to start process, "' + cmd.executable + '" exec not found'
|
||||
);
|
||||
bus.emit('error', code);
|
||||
process.exit();
|
||||
}
|
||||
@@ -227,7 +231,8 @@ function run(options) {
|
||||
return restart();
|
||||
}
|
||||
|
||||
if (code === 0) { // clean exit - wait until file change to restart
|
||||
if (code === 0) {
|
||||
// clean exit - wait until file change to restart
|
||||
if (runCmd) {
|
||||
utils.log.status('clean exit - waiting for changes before restart');
|
||||
}
|
||||
@@ -241,8 +246,9 @@ function run(options) {
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
utils.log.fail('app crashed - waiting for file changes before' +
|
||||
' starting...');
|
||||
utils.log.fail(
|
||||
'app crashed - waiting for file changes before' + ' starting...'
|
||||
);
|
||||
child = null;
|
||||
}
|
||||
}
|
||||
@@ -267,21 +273,25 @@ function run(options) {
|
||||
// swallow the stdin error if it happens
|
||||
// ref: https://github.com/remy/nodemon/issues/1195
|
||||
if (hasStdio) {
|
||||
child.stdin.on('error', () => { });
|
||||
child.stdin.on('error', () => {});
|
||||
process.stdin.pipe(child.stdin);
|
||||
} else {
|
||||
if (child.stdout) {
|
||||
child.stdout.pipe(process.stdout);
|
||||
} else {
|
||||
utils.log.error('running an unsupported version of node ' +
|
||||
process.version);
|
||||
utils.log.error('nodemon may not work as expected - ' +
|
||||
'please consider upgrading to LTS');
|
||||
utils.log.error(
|
||||
'running an unsupported version of node ' + process.version
|
||||
);
|
||||
utils.log.error(
|
||||
'nodemon may not work as expected - ' +
|
||||
'please consider upgrading to LTS'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bus.once('exit', function () {
|
||||
if (child && process.stdin.unpipe) { // node > 0.8
|
||||
if (child && process.stdin.unpipe) {
|
||||
// node > 0.8
|
||||
process.stdin.unpipe(child.stdin);
|
||||
}
|
||||
});
|
||||
@@ -300,14 +310,16 @@ function waitForSubProcesses(pid, callback) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
utils.log.status(`still waiting for ${pids.length} sub-process${
|
||||
pids.length > 2 ? 'es' : ''} to finish...`);
|
||||
utils.log.status(
|
||||
`still waiting for ${pids.length} sub-process${
|
||||
pids.length > 2 ? 'es' : ''
|
||||
} to finish...`
|
||||
);
|
||||
setTimeout(() => waitForSubProcesses(pid, callback), 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function kill(child, signal, callback) {
|
||||
|
||||
if (!callback) {
|
||||
callback = noop;
|
||||
}
|
||||
@@ -317,15 +329,14 @@ function kill(child, signal, callback) {
|
||||
try {
|
||||
exec('taskkill /pid ' + child.pid + ' /T /F');
|
||||
} catch (e) {
|
||||
utils.log.error("Could not shutdown sub process cleanly");
|
||||
utils.log.error('Could not shutdown sub process cleanly');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// We are handling a 'SIGKILL' POSIX signal under Windows the
|
||||
// same way it is handled on a UNIX system: We are performing
|
||||
// a hard shutdown without waiting for the process to clean-up.
|
||||
if (signal === 'SIGKILL' || osRelease < 10) {
|
||||
|
||||
debug('terminating process group by force: %s', child.pid);
|
||||
|
||||
// We are using the taskkill utility to terminate the whole
|
||||
@@ -337,35 +348,36 @@ function kill(child, signal, callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We are using the Windows Management Instrumentation Command-line
|
||||
// (wmic.exe) to resolve the sub-child process identifier, because the
|
||||
// 'child' process in this context is actually a cmd.exe wrapper.
|
||||
// We want to send the termination signal directly to the node process.
|
||||
// The '2> nul' silences the no process found error message.
|
||||
const resultBuffer = execSync(
|
||||
`wmic process where (ParentProcessId=${child.pid}) get ProcessId 2> nul`
|
||||
);
|
||||
const result = resultBuffer.toString().match(/^[0-9]+/m);
|
||||
|
||||
// If there is no sub-child process we fall back to the child process.
|
||||
const processId = Array.isArray(result) ? result[0] : child.pid;
|
||||
|
||||
debug('sending kill signal SIGINT to process: %s', processId);
|
||||
|
||||
// We are using the standalone 'windows-kill' executable to send the
|
||||
// standard POSIX signal 'SIGINT' to the node process. This fixes #1720.
|
||||
const windowsKill = path.normalize(
|
||||
`${__dirname}/../../bin/windows-kill.exe`
|
||||
);
|
||||
|
||||
// We have to detach the 'windows-kill' execution completely from this
|
||||
// process group to avoid terminating the nodemon process itself.
|
||||
// See: https://github.com/alirdn/windows-kill#how-it-works--limitations
|
||||
//
|
||||
// Therefore we are using 'start' to create a new cmd.exe context.
|
||||
// The '/min' option hides the new terminal window and the '/wait'
|
||||
// option lets the process wait for the command to finish.
|
||||
try {
|
||||
// We are using the Windows Management Instrumentation Command-line
|
||||
// (wmic.exe) to resolve the sub-child process identifier, because the
|
||||
// 'child' process in this context is actually a cmd.exe wrapper.
|
||||
// We want to send the termination signal directly to the node process.
|
||||
// The '2> nul' silences the no process found error message.
|
||||
const resultBuffer = execSync(
|
||||
`wmic process where (ParentProcessId=${child.pid}) get ProcessId 2> nul`
|
||||
);
|
||||
const result = resultBuffer.toString().match(/^[0-9]+/m);
|
||||
|
||||
// If there is no sub-child process we fall back to the child process.
|
||||
const processId = Array.isArray(result) ? result[0] : child.pid;
|
||||
|
||||
debug('sending kill signal SIGINT to process: %s', processId);
|
||||
|
||||
// We are using the standalone 'windows-kill' executable to send the
|
||||
// standard POSIX signal 'SIGINT' to the node process. This fixes #1720.
|
||||
const windowsKill = path.normalize(
|
||||
`${__dirname}/../../bin/windows-kill.exe`
|
||||
);
|
||||
|
||||
// We have to detach the 'windows-kill' execution completely from this
|
||||
// process group to avoid terminating the nodemon process itself.
|
||||
// See: https://github.com/alirdn/windows-kill#how-it-works--limitations
|
||||
//
|
||||
// Therefore we are using 'start' to create a new cmd.exe context.
|
||||
// The '/min' option hides the new terminal window and the '/wait'
|
||||
// option lets the process wait for the command to finish.
|
||||
|
||||
execSync(
|
||||
`start "windows-kill" /min /wait "${windowsKill}" -SIGINT ${processId}`
|
||||
);
|
||||
@@ -373,7 +385,6 @@ function kill(child, signal, callback) {
|
||||
taskKill();
|
||||
}
|
||||
callback();
|
||||
|
||||
} else {
|
||||
// we use psTree to kill the full subtree of nodemon, because when
|
||||
// spawning processes like `coffee` under the `--debug` flag, it'll spawn
|
||||
@@ -395,15 +406,13 @@ function kill(child, signal, callback) {
|
||||
|
||||
child.kill(signal);
|
||||
|
||||
pids.sort().forEach(pid => exec(`kill -${sig} ${pid}`, noop));
|
||||
pids.sort().forEach((pid) => exec(`kill -${sig} ${pid}`, noop));
|
||||
|
||||
waitForSubProcesses(child.pid, () => {
|
||||
// finally kill the main user process
|
||||
exec(`kill -${sig} ${child.pid}`, callback);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,7 +519,9 @@ bus.on('restart', function () {
|
||||
// remove the child file on exit
|
||||
process.on('exit', function () {
|
||||
utils.log.detail('exiting');
|
||||
if (child) { child.kill(); }
|
||||
if (child) {
|
||||
child.kill();
|
||||
}
|
||||
});
|
||||
|
||||
// because windows borks when listening for the SIG* events
|
||||
@@ -520,10 +531,11 @@ if (!utils.isWindows) {
|
||||
process.once('SIGINT', () => bus.emit('quit', 130));
|
||||
process.once('SIGTERM', () => {
|
||||
bus.emit('quit', 143);
|
||||
if (child) { child.kill('SIGTERM'); }
|
||||
if (child) {
|
||||
child.kill('SIGTERM');
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = run;
|
||||
|
||||
2114
package-lock.json
generated
2114
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -47,11 +47,11 @@
|
||||
"async": "1.4.2",
|
||||
"coffee-script": "~1.7.1",
|
||||
"eslint": "^7.11.0",
|
||||
"husky": "^0.14.3",
|
||||
"istanbul": "^0.4.5",
|
||||
"husky": "^7.0.2",
|
||||
"mocha": "^2.5.3",
|
||||
"nyc": "^15.1.0",
|
||||
"proxyquire": "^1.8.0",
|
||||
"semantic-release": "^17.4.4",
|
||||
"semantic-release": "^18.0.0",
|
||||
"should": "~4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -64,7 +64,7 @@
|
||||
"supports-color": "^5.5.0",
|
||||
"touch": "^3.1.0",
|
||||
"undefsafe": "^2.0.3",
|
||||
"update-notifier": "^4.1.0"
|
||||
"update-notifier": "^5.1.0"
|
||||
},
|
||||
"version": "0.0.0-development",
|
||||
"funding": {
|
||||
|
||||
Reference in New Issue
Block a user