motion
Version:
motion - moving development forward
75 lines (74 loc) • 11.8 kB
JSON
{
"_args": [
[
"liftoff@https://registry.npmjs.org/liftoff/-/liftoff-2.2.0.tgz",
"/Users/nw/flint/packages/flint"
]
],
"_from": "liftoff@>=2.1.0 <3.0.0",
"_id": "liftoff@2.2.0",
"_inCache": true,
"_location": "/liftoff",
"_phantomChildren": {},
"_requested": {
"name": "liftoff",
"raw": "liftoff@https://registry.npmjs.org/liftoff/-/liftoff-2.2.0.tgz",
"rawSpec": "https://registry.npmjs.org/liftoff/-/liftoff-2.2.0.tgz",
"scope": null,
"spec": "https://registry.npmjs.org/liftoff/-/liftoff-2.2.0.tgz",
"type": "remote"
},
"_requiredBy": [
"/gulp"
],
"_resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.2.0.tgz",
"_shasum": "f5fcfa4583113159d12935a8a0616f50128b5753",
"_shrinkwrap": null,
"_spec": "liftoff@https://registry.npmjs.org/liftoff/-/liftoff-2.2.0.tgz",
"_where": "/Users/nw/flint/packages/flint",
"author": {
"name": "Tyler Kellen",
"url": "http://goingslowly.com/"
},
"bugs": {
"url": "https://github.com/tkellen/node-liftoff/issues"
},
"dependencies": {
"extend": "^2.0.1",
"findup-sync": "^0.3.0",
"flagged-respawn": "^0.3.1",
"rechoir": "^0.6.0",
"resolve": "^1.1.6"
},
"description": "Launch your command line tool with ease.",
"devDependencies": {
"chai": "^2.3.0",
"coffee-script": "^1.9.2",
"istanbul": "^0.3.14",
"jscs": "^1.13.1",
"jshint": "^2.7.0",
"mocha": "^2.1.0",
"sinon": "~1.12.2"
},
"engines": {
"node": ">= 0.8"
},
"homepage": "https://github.com/tkellen/node-liftoff",
"keywords": [
"command line"
],
"license": "MIT",
"main": "index.js",
"name": "liftoff",
"optionalDependencies": {},
"readme": "<p align=\"center\">\n <a href=\"http://liftoffjs.com\">\n <img height=\"100\" width=\"297\" src=\"https://cdn.rawgit.com/tkellen/js-liftoff/master/artwork/liftoff.svg\"/>\n </a>\n</p>\n\n# liftoff [](http://travis-ci.org/tkellen/js-liftoff) [](https://ci.appveyor.com/project/tkellen/js-liftoff/branch/master)\n\n> Launch your command line tool with ease.\n\n[](https://nodei.co/npm/liftoff/)\n\n## What is it?\n[See this blog post](http://weblog.bocoup.com/building-command-line-tools-in-node-with-liftoff/), [check out this proof of concept](http://github.com/tkellen/node-hacker), or read on.\n\nSay you're writing a CLI tool. Let's call it [hacker](http://github.com/tkellen/node-hacker). You want to configure it using a `Hackerfile`. This is node, so you install `hacker` locally for each project you use it in. But, in order to get the `hacker` command in your PATH, you also install it globally.\n\nNow, when you run `hacker`, you want to configure what it does using the `Hackerfile` in your current directory, and you want it to execute using the local installation of your tool. Also, it'd be nice if the `hacker` command was smart enough to traverse up your folders until it finds a `Hackerfile`—for those times when you're not in the root directory of your project. Heck, you might even want to launch `hacker` from a folder outside of your project by manually specifying a working directory. Liftoff manages this for you.\n\nSo, everything is working great. Now you can find your local `hacker` and `Hackerfile` with ease. Unfortunately, it turns out you've authored your `Hackerfile` in coffee-script, or some other JS variant. In order to support *that*, you have to load the compiler for it, and then register the extension for it with node. Good news, Liftoff can do that, and a whole lot more, too.\n\n## API\n\n### constructor(opts)\n\nCreate an instance of Liftoff to invoke your application.\n\nAn example utilizing all options:\n```js\nconst Hacker = new Liftoff({\n name: 'hacker',\n processTitle: 'hacker',\n moduleName: 'hacker',\n configName: 'hackerfile',\n extensions: {\n '.js': null,\n '.json': null,\n '.coffee': 'coffee-script/register'\n },\n v8flags: ['--harmony'] // or v8flags: require('v8flags');\n});\n```\n\n#### opts.name\n\nSugar for setting `processTitle`, `moduleName`, `configName` automatically.\n\nType: `String` \nDefault: `null`\n\nThese are equivalent:\n```js\nconst Hacker = Liftoff({\n processTitle: 'hacker',\n moduleName: 'hacker',\n configName: 'hackerfile'\n});\n```\n```js\nconst Hacker = Liftoff({name:'hacker'});\n```\n\n#### opts.moduleName\n\nSets which module your application expects to find locally when being run.\n\nType: `String` \nDefault: `null`\n\n#### opts.configName\n\nSets the name of the configuration file Liftoff will attempt to find. Case-insensitive.\n\nType: `String` \nDefault: `null`\n\n#### opts.extensions\n\nSet extensions to include when searching for a configuration file. If an external module is needed to load a given extension (e.g. `.coffee`), the module name should be specified as the value for the key.\n\nType: `Object` \nDefault: `{\".js\":null,\".json\":null}`\n\n**Examples:**\n\nIn this example Liftoff will look for `myappfile{.js,.json,.coffee}`. If a config with the extension `.coffee` is found, Liftoff will try to require `coffee-script/require` from the current working directory.\n```js\nconst MyApp = new Liftoff({\n name: 'myapp'\n extensions: {\n '.js': null,\n '.json': null,\n '.coffee': 'coffee-script/register'\n }\n});\n```\n\nIn this example, Liftoff will look for `.myapp{rc}`.\n```js\nconst MyApp = new Liftoff({\n name: 'myapp',\n configName: '.myapp',\n extensions: {\n 'rc': null\n }\n});\n```\n\nIn this example, Liftoff will automatically attempt to load the correct module for any javascript variant supported by [node-interpret](https://github.com/tkellen/node-interpret) (as long as it does not require a register method).\n\n```js\nconst MyApp = new Liftoff({\n name: 'myapp',\n extensions: require('interpret').jsVariants\n});\n```\n#### opts.v8flags\n\nAny flag specified here will be applied to node, not your program. Useful for supporting invocations like `myapp --harmony command`, where `--harmony` should be passed to node, not your program. This functionality is implemented using [flagged-respawn](http://github.com/tkellen/node-flagged-respawn). To support all v8flags, see [node-v8flags](https://github.com/tkellen/node-v8flags).\n\nType: `Array|Function` \nDefault: `null`\n\nIf this method is a function, it should take a node-style callback that yields an array of flags.\n\n#### opts.processTitle\n\nSets what the [process title](http://nodejs.org/api/process.html#process_process_title) will be.\n\nType: `String` \nDefault: `null`\n\n#### opts.completions(type)\n\nA method to handle bash/zsh/whatever completions.\n\nType: `Function` \nDefault: `null`\n\n## launch(opts, callback(env))\nLaunches your application with provided options, builds an environment, and invokes your callback, passing the calculated environment as the first argument.\n\n##### Example Configuration w/ Options Parsing:\n```js\nconst Liftoff = require('liftoff');\nconst MyApp = new Liftoff({name:'myapp'});\nconst argv = require('minimist')(process.argv.slice(2));\nconst invoke = function (env) {\n console.log('my environment is:', env);\n console.log('my cli options are:', argv);\n console.log('my liftoff config is:', this);\n};\nMyApp.launch({\n cwd: argv.cwd,\n configPath: argv.myappfile,\n require: argv.require,\n completion: argv.completion\n}, invoke);\n```\n\n#### opts.cwd\n\nChange the current working directory for this launch. Relative paths are calculated against `process.cwd()`.\n\nType: `String` \nDefault: `process.cwd()`\n\n**Example Configuration:**\n```js\nconst argv = require('minimist')(process.argv.slice(2));\nMyApp.launch({\n cwd: argv.cwd\n}, invoke);\n```\n\n**Matching CLI Invocation:**\n```\nmyapp --cwd ../\n```\n\n#### opts.configPath\n\nDon't search for a config, use the one provided. **Note:** Liftoff will assume the current working directory is the directory containing the config file unless an alternate location is explicitly specified using `cwd`.\n\nType: `String` \nDefault: `null`\n\n**Example Configuration:**\n```js\nvar argv = require('minimist')(process.argv.slice(2));\nMyApp.launch({\n configPath: argv.myappfile\n}, invoke);\n```\n\n**Matching CLI Invocation:**\n```\nmyapp --myappfile /var/www/project/Myappfile.js\n```\n\n**Examples using `cwd` and `configPath` together:**\n\nThese are functionally identical:\n```\nmyapp --myappfile /var/www/project/Myappfile.js\nmyapp --cwd /var/www/project\n```\n\nThese can run myapp from a shared directory as though it were located in another project:\n```\nmyapp --myappfile /Users/name/Myappfile.js --cwd /var/www/project1\nmyapp --myappfile /Users/name/Myappfile.js --cwd /var/www/project2\n```\n\n#### opts.require\n\nA string or array of modules to attempt requiring from the local working directory before invoking the launch callback.\n\nType: `String|Array` \nDefault: `null`\n\n**Example Configuration:**\n```js\nvar argv = require('minimist')(process.argv.slice(2));\nMyApp.launch({\n require: argv.require\n}, invoke);\n```\n\n**Matching CLI Invocation:**\n```js\nmyapp --require coffee-script/register\n```\n\n#### callback(env)\n\nA function to start your application. When invoked, `this` will be your instance of Liftoff. The `env` param will contain the following keys:\n\n- `cwd`: the current working directory\n- `require`: an array of modules that liftoff tried to pre-load\n- `configNameSearch`: the config files searched for\n- `configPath`: the full path to your configuration file (if found)\n- `configBase`: the base directory of your configuration file (if found)\n- `modulePath`: the full path to the local module your project relies on (if found)\n- `modulePackage`: the contents of the local module's package.json (if found)\n\n### events\n\n#### require(name, module)\n\nEmitted when a module is pre-loaded.\n\n```js\nvar Hacker = new Liftoff({name:'hacker'});\nHacker.on('require', function (name, module) {\n console.log('Requiring external module: '+name+'...');\n // automatically register coffee-script extensions\n if (name === 'coffee-script') {\n module.register();\n }\n});\n```\n\n#### requireFail(name, err)\n\nEmitted when a requested module cannot be preloaded.\n\n```js\nvar Hacker = new Liftoff({name:'hacker'});\nHacker.on('requireFail', function (name, err) {\n console.log('Unable to load:', name, err);\n});\n```\n\n#### respawn(flags, child)\n\nEmitted when Liftoff re-spawns your process (when a [`nodeFlag`](#optsnodeflags) is detected).\n\n```js\nvar Hacker = new Liftoff({\n name: 'hacker',\n nodeFlags: ['--harmony']\n});\nHacker.on('respawn', function (flags, child) {\n console.log('Detected node flags:', flags);\n console.log('Respawned to PID:', child.pid);\n});\n```\n\nEvent will be triggered for this command:\n`hacker --harmony commmand`\n\n## Examples\n\nCheck out how [gulp](https://github.com/gulpjs/gulp/blob/master/bin/gulp.js) uses Liftoff.\n\nFor a bare-bones example, try [the hacker project](https://github.com/tkellen/node-hacker/blob/master/bin/hacker.js).\n\nTo try the example, do the following:\n\n1. Install the sample project `hacker` with `npm install -g hacker`.\n2. Make a `Hackerfile.js` with some arbitrary javascript it.\n3. Install hacker next to it with `npm install hacker`.\n3. Run `hacker` while in the same parent folder.\n",
"readmeFilename": "README.md",
"repository": {
"type": "git",
"url": "git://github.com/tkellen/node-liftoff.git"
},
"scripts": {
"test": "jshint lib index.js && jscs lib index.js && mocha -t 5000 -b -R spec test/index"
},
"version": "2.2.0"
}