Socket
Socket
Sign inDemoInstall

main

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

main - npm Package Compare versions

Comparing version 0.0.1 to 0.0.22

examples/arguments.js

221

index.js

@@ -0,12 +1,217 @@

var when = require('when')
, sequence = require('when/sequence')
, extend = require('util')._extend;
var Tools = function(usage, flags) {
var self = this;
self.optimist = require('optimist');
self.tools = require('./tools');
self.toolsSync = require('./toolsSync');
//-------------------------------------------------------------------------
// Setup Optimist
//-------------------------------------------------------------------------
self.optimist.usage(usage);
if (flags) {
for (var key in flags) {
self.optimist.options(key, flags[key]);
}
}
// check for any errors & reset argv
self.optimist.argv = self.optimist.parse(process.argv);
// remove node/script path from pos args
self.optimist.argv._.splice(0, 2);
// set `self.flag`s to the values parsed (skip over $0 / "_" / others)
self.flags = {};
if (flags) {
for (var argvKey in self.optimist.argv) {
if (typeof flags[argvKey] !== 'undefined') {
self.flags[argvKey] = self.optimist.argv[argvKey];
}
}
}
self.help = self.optimist.help(); // pull out the static help message
self.args = self.optimist.argv._; // pull out the positional arguments
//-------------------------------------------------------------------------
// Setup Tool wrappers
//-------------------------------------------------------------------------
function returnSelf(fn) {
return function() {
fn.apply(null, arguments);
return self;
};
}
/*
Sync Tools
*/
// Non Chainable
self.str = self.toolsSync.str;
self.mktemp = self.toolsSync.mktemp;
self.exit = self.toolsSync.exit;
self.walkSync = self.toolsSync.walk;
self.readSync = self.toolsSync.read;
self.readStream = self.toolsSync.readStream;
self.writeStream = self.toolsSync.writeStream;
self.stdout = self.toolsSync.stdout;
self.stderr = self.toolsSync.stderr;
// Chainable
self.out = returnSelf(self.toolsSync.out);
self.cout = returnSelf(self.toolsSync.cout);
self.err = returnSelf(self.toolsSync.err);
self.cerr = returnSelf(self.toolsSync.cerr);
self.writeSync = returnSelf(self.toolsSync.write);
self.appendSync = returnSelf(self.toolsSync.append);
self.existsSync = returnSelf(self.toolsSync.exists);
self.mkdirSync = returnSelf(self.toolsSync.mkdir);
self.touchSync = returnSelf(self.toolsSync.touch);
self.rmSync = returnSelf(self.toolsSync.rm);
/*
Async Tools
*/
self.exists = self.tools.exists;
self.mkdir = self.tools.mkdir;
self.write = self.tools.write;
self.touch = self.tools.touch;
self.append = self.tools.append;
self.read = self.tools.read;
self.walk = self.tools.walk;
self.rm = self.tools.rm;
// Helpers for Async Tools
self.when = self.tools.when;
self.sequence = self.tools.sequence;
self.parallel = self.tools.parallel;
self.pipeline = self.tools.pipeline;
self.chain = self.tools.chain;
//-------------------------------------------------------------------------
// Class specific functions
//-------------------------------------------------------------------------
self.assert = {
// Positional Argument Asserts
// ---------------------------
argsLen: function(length) {
if (self.args.length !== length) {
self.cerr(self.help)
.cerr('Expected ' + length + ' positional arguments')
.cerr('Received ' + self.str(self.args)).exit(1);
}
return self;
},
argsLenGe: function(length) {
if (self.args.length < length) {
self.cerr(self.help)
.cerr('Expected at least ' + length + ' positional arguments')
.cerr('Received ' + self.str(self.args)).exit(1);
}
return self;
},
argsLenGt: function(length) {
if (self.args.length <= length) {
self.cerr(self.help)
.cerr('Expected more than ' + length + ' positional arguments')
.cerr('Received ' + self.str(self.args)).exit(1);
}
return self;
},
argsLenLe: function(length) {
if (self.args.length > length) {
self.cerr(self.help)
.cerr('Expected ' + length + ' or less positional arguments')
.cerr('Received ' + self.str(self.args)).exit(1);
}
return self;
},
argsLenLt: function(length) {
if (self.args.length >= length) {
self.cerr(self.help)
.cerr('Expected less than ' + length + ' positional arguments')
.cerr('Received ' + self.str(self.args)).exit(1);
}
return self;
}
// Other asserts to come
// ---------------------
};
/*
Retrieves the value of a positional argument or a flag based on if a number
or a string is provided.
@param {string|number} positionOrFlag
*/
self.getValue = function(positionOrFlag) {
if (typeof positionOrFlag === 'string') {
return self.optimist.argv[positionOrFlag]
}
if (typeof positionOrFlag === 'number') {
return self.optimist.argv._[positionOrFlag];
}
throw new Error('provide a position (number) or a flag (string)');
};
return extend(self.getValue, self);
};
var Main = function(currentModule) {
// ran directly? e.g. node script & not required
var ranDirectly = !currentModule.parent
, usage
, flags;
// sets the usage
this.usage = function() {
var newUsage = Array.prototype.slice.call(arguments).join('\n');
if (ranDirectly) {
usage = newUsage;
}
return this;
};
// sets the flags
this.flags = function(newFlags) {
if (ranDirectly && newFlags) {
flags = newFlags;
}
return this;
};
// Run the main function if we're running this script directly
this.run = function(mainFn) {
if (ranDirectly) {
mainFn(new Tools(usage, flags));
}
};
};
/*
@param {function} mainFn - Function that takes optimist argv
Invoked from another script as:
require('main')(module)
`module` isn't a variable... it's a global that exists in every node script.
@param {object} currentModule - NodeJS module that we will use
*/
module.exports = function(mainFn) {
// If the script that required US does not have a parent, then
// we assume it was run the the CLI (and not required!)
if (!module.parent.parent) {
var argv = require('optimist').argv;
mainFn(argv);
}
module.exports = function(currentModule) {
return new Main(currentModule);
};

19

package.json
{
"name": "main",
"version": "0.0.1",
"version": "0.0.22",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"description": "Provides useful tools for writing command line scripts",
"repository": {

@@ -16,4 +14,9 @@ "type": "git",

"dependencies": {
"optimist": "~0.6.0"
"optimist": "~0.6.0",
"temp": "~0.6.0",
"when": "~2.5.1"
},
"scripts": {
"test": "node_modules/.bin/mocha test"
},
"author": "Trevor Senior <trevor@tsenior.com> (http://tsenior.com/)",

@@ -23,3 +26,9 @@ "license": "MIT",

"url": "https://github.com/trevorsenior/node-main/issues"
},
"devDependencies": {
"chai": "~1.8.1",
"chai-as-promised": "~4.1.0",
"mocha": "~1.17.0",
"mocha-as-promised": "~2.0.0"
}
}

@@ -1,39 +0,161 @@

node-main
=========
# node-main
A *very* basic module that only runs code if the script is ran directly (And not required). It utilizes [optimist](https://github.com/substack/node-optimist) for argument parsing. See [this SO question](http://stackoverflow.com/q/4981891/586621) for more information on how it works.
At the most basic level, `node-main` provides an easy way to specify an [entry point](http://en.wikipedia.org/wiki/Entry_point) for a script that is ran on the command line. It allows us to call a block of code *only* when the script is executed from the command line. If the script is `require`'d into another node module, it will not execute the main block.
## Usage
`node-main` also supports automatic usage generation, and a whole plethora of tools that serve as shortcuts while writing command line scripts.
```javascript
require('main')(function(argv) {
// The code in here will only be executed if running from the CLI
//
// argv is the argv object that optimist produces, e.g.
// require('optimist').argv;
// Code out here will always run, as it is outside the main block
console.log('Hello');
require('main')(module)
.usage('./someScript [flags] <firstName> <lastName> <filePath>',
'',
'This simple script will write your first and last name',
'to a file. The middle initial is optional as a flag.')
.flags({
middleInitial: {
alias: 'm', default: '', describe: 'Middle Initial'
}
})
.run(function($) {
// code in this block only runs when called directly from the CLI
$.assert.argsLen(2);
var fullName = $(0) + $('middleInitial') + $(1);
var filePath = $(2);
$.writeSync(filePath, fullName).cout('done!');
});
```
## Example
Of course, this is only the tip of what's available. Visit the example directories and the documentation for more information
test.js
## Installation
npm install --save main
Don't forget the `--save` flag. It will preserve the version you are using as `node-main` is still going through many changes.
## Usage
For more advanced usage information that covers everything, please visit the [full documentation (WIP)](#).
### The Basics
You're going to need to require the main module in your script. This is the minumum boilerplate to use `node-main`:
```javascript
exports.foo = function() { return 'bar'; }
require('main')(module).run(function() {
// code here will be executed when ran from the CLI
});
```
require('main')(function(argv) {
console.log(exports.foo());
If you would like to set up usage information and flags, simply add those two before calling run like so:
```javascript
require('main')(module)
.usage(
'./someScript [options] <arg1> <arg2>',
'',
'We can expand this usage information to multiple',
'lines if we want to go into detail of how a ',
'script is to be used.')
.flags({
flagOne: { alias: 'o' },
flagTwo: { boolean: true },
flagThree: { demand: true, description: 'third flag' }
})
.run(function(scriptTools) { // SCRIPT TOOLS
// code here will be executed when ran from the CLI
});
```
Running from the terminal:
The flags use [`node-optimist`](https://github.com/substack/node-optimist) - so options that are valid there, will be valid in `node-main` (such as demand, boolean, alias, etc.).
$ node test.js
bar
Also note that I have included a `scriptTools` variable inside of the run function. This allows us to access the tools that help in writing CLI scripts. For the remainder of *The Basics*, I'll refer to the `scriptTools` variable as "`$`"
Using the module from another script will not execute the code in main:
```javascript
// the "scriptTools" can be named anything, even $
require('main')(module).run(function($) { /* ... */ });
```
#### Script Tools
Script tools provide shortcuts for repetitive things that come up frequently when writing CLI scripts.
Visit the [full documentation (WIP)](#) for an exhaustive list of the tools available for use. Visit the example directory to see some in use.
**argument/flag fetching**
If you wanted to fetch the value for flag 'foo' and get the first positional argument:
```javascript
var test = require('./test');
console.log(test.foo()); // 'bar'
$('foo'); // value of the flag foo
$(0); // the first positional argument
```
And array of received arguments can be accessed with `$.args` and an object containing all the flag values can be accessed with `$.flags`.
**printing to the console**
```javascript
$.cout('hello world'); //same as console.log
```
Others include `$.cerr` (console.error), `$.out` (process.stdout.write), `$.err` (process.stderr.write).
**files**
There are synchronous and asynchronous versions of all file operations. The sync ones are chainable and can be used in the following fashion:
```javascript
var file = '/tmp/README.md';
$.cout(
$.writeSync(file, '# Hello World')
.appendSync(file, 'foo bar')
.readSync(file)
);
```
The async versions use a promise based implementation. The above can be re-written using asynchronously using promises as such:
```javascript
var file = '/tmp/README.md';
$.write(file, '# Hello World').then(function() {
return $.append(file, 'foo bar');
}).then(function() {
return $.read(file);
}).then($.cout);
```
A non-exhaustive list of some other file functions (all have async counterparts)
```javascript
$.walkSync
$.existsSync
$.mkdirSync
$.touchSync
$.rmSync
```
There is also a `$.mktemp` function to generate a random file name in the operating systems temporary directory. It doesn't create the file - that's up to you.
**async helpers**
There are async helpers such as `$.chain`, `$.sequence`, and many more to help streamline further, but these are well above the basics. Using `$.chain`, the async file example above can be reduced to:
```javascript
$.chain(
[ $.write, file, '# Hello World' ],
[ $.append, file, 'foo bar' ],
[ $.read, file ],
[ $.cout ]
);
```
**that's all for now**
That should be enough to get you started.
## Contributing
Feel free to add in new features as long as they are accompanied with test cases. Running `npm test` should get you started.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc