-
Notifications
You must be signed in to change notification settings - Fork 947
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[refactor bin] Remove options parsing from bin
- Loading branch information
Showing
1 changed file
with
2 additions
and
278 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,282 +1,6 @@ | ||
#!/usr/bin/env node | ||
|
||
var path = require('path'), | ||
fs = require('fs'), | ||
winston = require('winston'), | ||
util = require('util'), | ||
utile = require('utile'), | ||
forever = require('./../lib/forever'); | ||
var forever = require('./../lib/forever'); | ||
|
||
var action, accepts = [ | ||
'config', | ||
'cleanlogs', | ||
'clear', | ||
'columns', | ||
'list', | ||
'logs', | ||
'service-install', | ||
'service-add', | ||
'service-start', | ||
'service-stop', | ||
'service-restart', | ||
'start', | ||
'stop', | ||
'stopall', | ||
'set', | ||
'restart' | ||
]; | ||
forever.cli.startCLI(); | ||
|
||
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', 'w', 'watch', 'plain']).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>', | ||
' logs Lists log files for all forever processes', | ||
' logs <script|index> Tails the logs for <script|index>', | ||
' columns add <col> Adds the specified column to the output in `forever list`', | ||
' columns rm <col> Removed the specified column from the output in `forever list`', | ||
' columns set <cols> Set all columns for the output in `forever list`', | ||
' 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', | ||
' -p PATH Base path for all forever related files (pid files, etc.)', | ||
' -c COMMAND COMMAND to execute (defaults to node)', | ||
' -a, --append Append logs', | ||
' --pidfile The pid file', | ||
' --sourceDir The source directory for which SCRIPT is relative to', | ||
' --minUptime Minimum uptime (millis) for a script to not be considered "spinning"', | ||
' --spinSleepTime Time to wait (millis) between launches of a spinning script.', | ||
' --plain Disable command line colors', | ||
' -d, --debug Forces forever to log debug output', | ||
' -v, --verbose Turns on the verbose messages from Forever', | ||
' -s, --silent Run the child script silencing stdout and stderr', | ||
' -w, --watch Watch for file changes', | ||
' -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', | ||
'logs', | ||
'stopall', | ||
'cleanlogs', | ||
'service-install', | ||
'service-start', | ||
'service-stop', | ||
'service-restart' | ||
].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()) | ||
&& (!argv.c && !argv.command)) { | ||
return util.puts(help); | ||
} | ||
|
||
var mappings = { | ||
'c': 'command', | ||
'e': 'errFile', | ||
'l': 'logFile', | ||
'a': 'appendLog', | ||
'append': 'appendLog', | ||
'm': 'max', | ||
'o': 'outFile', | ||
'p': 'path', | ||
'pidfile': 'pidFile', | ||
's': 'silent', | ||
'silent': 'silent', | ||
'sourceDir': 'sourceDir', | ||
'minUptime': 'minUptime', | ||
'spinSleepTime': 'spinSleepTime', | ||
'plain': 'plain', | ||
'v': 'verbose', | ||
'verbose': 'verbose', | ||
'w': 'watch', | ||
'watch': 'watch', | ||
'd': 'debug', | ||
'debug': 'debug' | ||
}; | ||
|
||
// | ||
// 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); | ||
} | ||
else if (argv.c || argv.command) { | ||
options.options = process.argv.splice(process.argv.indexOf(argv.c || argv.command) + 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', 'watch', 'w', 'plain']).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 (typeof options['minUptime'] !== 'undefined') { | ||
options['minUptime'] = parseFloat(options['minUptime']); | ||
} | ||
if (typeof options['spinSleepTime'] !== 'undefined') { | ||
options['spinSleepTime'] = parseFloat(options['spinSleepTime']); | ||
} | ||
|
||
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 = utile.randomString(4); | ||
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', 'watch', 'plain'].forEach(function (key) { | ||
var target = mappings[key], | ||
value = forever.config.get(key); | ||
|
||
if (value) { | ||
options[target] = options[target] || value === 'true'; | ||
} | ||
}); | ||
|
||
// | ||
// If options.plain is false, set colors.mode = 'none' to avoid colorful | ||
// output (see https://github.com/indexzero/forever/issues/112 ). | ||
// Modifying colors.mode turns off output coloring for all node modules | ||
// which use colors because of node.js require caching. | ||
// | ||
if (options.plain) { | ||
require('colors').mode = 'none'; | ||
} | ||
|
||
// | ||
// Pass the source dir to spawn | ||
// | ||
options.spawnWith = { | ||
cwd: options.sourceDir | ||
}; | ||
|
||
// | ||
// Configure winston for forever based on the CLI options | ||
// | ||
if (options.verbose) { | ||
forever.log.transports.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)) { | ||
forever.log.silly('Loading forever with config: ', config); | ||
forever.load(config); | ||
forever.log.silly('Loaded forever successfully.'); | ||
} | ||
|
||
// | ||
// If there is an uncaught exception then log | ||
// it to the default `forever._debug`. | ||
// | ||
process.on('uncaughtException', function (err) { | ||
forever._debug(); | ||
forever.log.error('uncaughtException'); | ||
forever.log.error(err.message); | ||
forever.log.error(err.stack); | ||
}); | ||
|
||
// | ||
// If we should debug this forever process then | ||
// configure it to do so. | ||
// | ||
if (argv.d || argv.debug) { | ||
forever.log.warn('Forever debugging enabled'); | ||
forever._debug(); | ||
} | ||
|
||
if (action === 'set') { | ||
// | ||
// If this is a set action then get the first | ||
// value from the options and continue. | ||
// | ||
options = options.options[0]; | ||
} | ||
else if (action === 'columns') { | ||
// | ||
// Otherwise if this is a `forever columns` | ||
// operation then update the action, options, | ||
// and file then continue. | ||
// | ||
action = [action, file]; | ||
options = options.options; | ||
file = null; | ||
} | ||
|
||
forever.cli.exec(action, file, options); |