Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 185 lines (164 sloc) 5.447 kB
#!/usr/bin/env node
var path = require('path'),
fs = require('fs'),
winston = require('winston'),
sys = require('sys'),
forever = require('./../lib/forever');
var accepts = ['start', 'stop', 'stopall', 'list', 'config', 'clear', 'set', 'cleanlogs', 'restart'], action;
if (accepts.indexOf(process.argv[2]) !== -1) {
action = process.argv.splice(2,1)[0];
}
var argv = require('optimist').boolean(['v', 'verbose', 'a', 'append', 's', 'silent']).argv;
var help = [
'usage: forever [action] [options] SCRIPT [script-options]',
'',
'Monitors the script specified in the current process or as a daemon',
'',
'actions:',
' start Start SCRIPT as a daemon',
' stop Stop the daemon SCRIPT',
' stopall Stop all running forever scripts',
' restart Restart the daemon SCRIPT',
' list List all running forever scripts',
' config Lists all forever user configuration',
' set <key> <val> Sets the specified forever config <key>',
' clear <key> Clears the specified forever config <key>',
' cleanlogs [CAREFUL] Deletes all historical forever log files',
'',
'options:',
' -m MAX Only run the specified script MAX times',
' -l LOGFILE Logs the forever output to LOGFILE',
' -o OUTFILE Logs stdout from child script to OUTFILE',
' -e ERRFILE Logs stderr from child script to ERRFILE',
' -d SOURCEDIR The source directory for which SCRIPT is relative to',
' -p PATH Base path for all forever related files (pid files, etc.)',
' -c COMMAND COMMAND to execute (defaults to node)',
' --pidfile The pid file',
' -a, --append Append logs',
' -v, --verbose Turns on the verbose messages from Forever',
' -s, --silent Run the child script silencing stdout and stderr',
' -h, --help You\'re staring at it',
'',
'[Long Running Process]',
' The forever process will continue to run outputting log messages to the console.',
' ex. forever -o out.log -e err.log my-script.js',
'',
'[Daemon]',
' The forever process will run as a daemon which will make the target process start',
' in the background. This is extremely useful for remote starting simple node.js scripts',
' without using nohup. It is recommended to run start with -o -l, & -e.',
' ex. forever start -l forever.log -o out.log -e err.log my-daemon.js',
' forever stop my-daemon.js',
''
].join('\n');
function isSimpleAction () {
return ['config', 'list', 'stopall', 'cleanlogs'].indexOf(action) !== -1;
};
//
// Show help prompt if requested or if the
// incorrect usage options are supplied
//
if (argv.h || argv.help ||
(argv._.length === 0 && !isSimpleAction())) {
sys.puts(help);
return;
}
var mappings = {
'c': 'command',
'e': 'errFile',
'd': 'sourceDir',
'l': 'logFile',
'a': 'appendLog',
'append': 'appendLog',
'm': 'max',
'o': 'outFile',
'p': 'path',
'pidfile': 'pidFile',
's': 'silent',
'silent': 'silent',
'v': 'verbose',
'verbose': 'verbose'
};
//
// If we are passed more than one non-hyphenated
// options, only use the first one. Assume the
// rest are pass-through for the child process
//
var file = argv._[0], options = {};
if (file) {
//
// Setup pass-thru options for child-process
//
options.options = process.argv.splice(process.argv.indexOf(file)).splice(1);
}
//
// Now that we've removed the target script options
// reparse the options and configure the forever settings
//
argv = require('optimist')(process.argv).boolean(['v', 'verbose', 'a', 'append', 's', 'silent']).argv;
Object.keys(argv).forEach(function (key) {
if (mappings[key] && argv[key]) {
options[mappings[key]] = argv[key];
}
});
if (typeof options['max'] === 'undefined') {
//
// If max isn't specified set it to run forever
//
options.forever = true;
}
if (!options.sourceDir) {
//
// Set the sourceDir of the options for graceful
// restarting outside of the main directory
//
options.sourceDir = file && file[0] !== '/' ? process.cwd() : '/';
}
var uid = forever.randomString(24);
options.uid = uid;
options.pidFile = options.pidFile || uid + '.pid';
options.logFile = argv.l || uid + '.log';
//
// Check for existing global config and set each
// key appropriately if it exists.
//
['append', 'silent', 'verbose'].forEach(function (key) {
var target = mappings[key],
value = forever.config.get(key);
if (value) {
options[target] = options[target] || value === 'true';
}
});
//
// Pass the source dir to spawn
//
options.spawnWith = {
cwd: options.sourceDir
};
//
// Configure winston for forever based on the CLI options
//
winston.defaultTransports().console.timestamp = false;
winston.defaultTransports().console.colorize = true;
if (options.verbose) {
winston.defaultTransports().console.level = 'silly';
}
//
// Setup configurations for forever
//
var config = {
root: argv.p
};
//
// Only call `forever.load()` if the root path is different than
// the default root exposed by forever.
//
if (config.root && config.root !== forever.root) {
winston.silly('Loading forever with config: ', config);
forever.load(config);
winston.silly('Loaded forever successfully.');
}
if (action === 'set') {
options = options.options[0];
}
forever.cli.exec(action, file, options);
Jump to Line
Something went wrong with that request. Please try again.