Skip to content

Commit

Permalink
Using async
Browse files Browse the repository at this point in the history
  • Loading branch information
Hypercubed committed Aug 23, 2013
1 parent 7549e07 commit b5515bf
Show file tree
Hide file tree
Showing 19 changed files with 311 additions and 336 deletions.
73 changes: 45 additions & 28 deletions Readme.md
Expand Up @@ -5,7 +5,7 @@ This is a work in progress, experiment, proof of concept, and/or waist of time.

# Description

autocmdr is a command runner, command builder, and command line interface app builder. autocmdr itself was partially built using autocmdr. Also see the obligatory todo app here [todo-md](https://github.com/Hypercubed/todo-md) (Works with GFM task lists!!).
autocmdr is a command runner, command builder, and command line interface application builder. autocmdr itself was partially built using autocmdr. Also see the obligatory todo app here [todo-md](https://github.com/Hypercubed/todo-md) (Works with GFM task lists!!).

Warning... The usage is changing rapidly. I'm still discovering new ways to use this. Feedback is welcome.

Expand All @@ -26,19 +26,19 @@ autocmdr is a CLI application builder. autocmdr itself is CLI that includes a r

Essentially autocmdr works in three modes. Local detached mode, global builder mode (accessed using the `-g` switch on the command line), and library mode. In local mode autocmdr (executing `autocmdr` without the `-g` flag) will run any commands specified in the current working directory's (cwd's) `cmds/` folder. By convention each file in the `cmds/` directory corresponds to one commander.js command, although this is not necessary. In this mode it is not necessary to install autocmdr in the current working directory, you are using the global autocmdr executable with the local `cmds/` commands.

In global builder mode (`autocmdr -g`) autocmdr is loaded with commands that enable management of the cwd's command files and building of autocmdr/commader.js CLI apps. You are still working in the cwd, but using the gloabl commands to manage the local commands. See below for more details and examples. In library mode a local commander.js based CLI executable is created that has access to autocmdr plugins (see below).
In global builder mode (`autocmdr -g`) autocmdr is loaded with commands that enable management of the cwd's command files and building of autocmdr/commader.js CLI apps. You are still working in the cwd, but using the global commands to manage the local commands. See below for more details and examples. In library mode a local commander.js based CLI executable is created that has access to autocmdr plug-ins (see below).

## Install autocmdr globally

npm install -g Hypercubed/autocmdr

## Using autocmdr as a task runner (Local detached mode)
## Using autocmdr as a task runner (Local detached mode)

When running in local mode (not using the `-g` flag) all commands located in the `cmds/` folder of the current working directory are automatically loaded. These commands can be be run by invoking `autocmdr commandname`. `autocmdr --help` will list help on these local commands. By using the globally installed `autocmdr` executable the rest of your project remains untouched so you can add commands to augment existing projects.

## Using autocmdr as a command builder (Global builder mode)

In global mode (`-g`) you can add and edit commands to the current working directory's `cmds/` folder. Refering to the example below notice that `autocmdr -g add mycmd` call is in global mode to add the `mycmd` to the cwd. The second `autocmdr mycmd` call executes the `mycmd` command. If you change to another directory these commands are no longer available.
In global mode (`-g`) you can add and edit commands to the current working directory's `cmds/` folder. Referring to the example below notice that `autocmdr -g add mycmd` call is in global mode to add the `mycmd` to the cwd. The second `autocmdr mycmd` call executes the `mycmd` command. If you change to another directory these commands are no longer available.

> cd example
> autocmdr -g --help
Expand Down Expand Up @@ -114,7 +114,7 @@ If a set of commands in a folder are useful globally you can convert a set of ta
autocmdr: description: (A autocmdr CLI app)
autocmdr: author: (J. Harshbarger)
autocmdr: license: (MIT)
autocmdr: Is this ok?: (yes)
autocmdr: Is this OK?: (yes)
info: Adding bin/example
info: Adding package.json
info: Adding Readme.md
Expand All @@ -128,6 +128,7 @@ If a set of commands in a folder are useful globally you can convert a set of ta
Commands:
mycmd [options]
config [key] [value] Get and set options
completion Print command completion script
Options:
-h, --help output usage information
Expand All @@ -145,6 +146,7 @@ If a set of commands in a folder are useful globally you can convert a set of ta
Commands:
mycmd [options]
config [key] [value] Get and set options
completion Print command completion script

Options:
-h, --help output usage information
Expand All @@ -153,13 +155,20 @@ If a set of commands in a folder are useful globally you can convert a set of ta

The new executable you just created, by default, will have access to the autocmdr plugins as well as the commands in the `cmds/` folder. Edit `bin/example` to change these defaults.

## Commander.js components
## autocmdr options

Commands and plugins are node.js modules that export a single initialization function. This function is called with a commander.js program and an optional options object. Commands and plugins have a simple syntax that doesn't deviate far from the syntax established by commander.js itself. See autocmdr's [commands](https://github.com/Hypercubed/autocmdr/tree/master/cmds) and [plugins](https://github.com/Hypercubed/autocmdr/tree/master/lib) for examples.
You can set options with this the `autocmdr config` command. `autocmdr config` will list all config variables. `autocmdr config name` will get a value, `autocmdr config name value` will set a value. Currently the following config options are available:

`autocmdr config author` will get/set the default cli author name
`autocmdr config editor` will get/set the default editor

# Commander.js components

Commands and plug-ins are node.js modules that export a single initialization function. This function is called with a commander.js program and an optional options object. Commands and plug-ins have a simple syntax that doesn't deviate far from the syntax established by commander.js itself. See autocmdr's [commands](https://github.com/Hypercubed/autocmdr/tree/master/cmds) and [plug-ins](https://github.com/Hypercubed/autocmdr/tree/master/lib) for examples.

## Command modules

The most basic form of a command module is shown below. Within the function the commander.js program is manipulated to add a single command as any other commander.js program (see [commander.js api documentation](http://visionmedia.github.io/commander.js/)).
The most basic form of a command module is shown below. Within the function the commander.js program is manipulated to add a single command as any other commander.js program (see [commander.js api documentationn](http://visionmedia.github.io/commander.js/)).

module.exports = function (program, options) {

Expand All @@ -173,63 +182,71 @@ The most basic form of a command module is shown below. Within the function the

};

## Plugin modules
## Plug-in modules

autocmdr plugin modules have the same structure as command modules. The only difference is that they are not designed to be automatically loaded. Plugins are loaded using node's require function again exporting a single initialization function; this time accepting an options object as teh second paramater. Below are the builtin autocmdr plugins.
autocmdr plug-in modules have the same structure as command modules. The only difference is that they are not designed to be automatically loaded. Plugins are loaded using node's require function again exporting a single initialization function; this time accepting an options object as the second parameter. Below are the builtin autocmdr plugins.

### loader

This plugin is what loads the `cmds/` modules.
This plug-in is what loads the `cmds/` modules.

Adding `require('autocmdr/lib/loader.js')(program)` will load all modules in the `cmds` folder just above the executable. This path can be overidden by setting the path option; for example `require('autocmdr/lib/loader.js')(program, { path: path.join(process.cwd(), 'cmds/') )` will load modules from the cwd's `/cmds` folder.
Adding `require('autocmdr/lib/loader.js')(program)` will load all modules in the `cmds` folder just above the executable. This path can be overridden by setting the path option; for example `require('autocmdr/lib/loader.js')(program, { path: path.join(process.cwd(), 'cmds/') )` will load modules from the cwd's `/cmds` folder.

### logger

The logger plugin uses [Winston](https://github.com/flatiron/winston) for logging.
The logger plug-in uses [Winston](https://github.com/flatiron/winston) for logging.

Adding `require('autocmdr/lib/logger.js')(program)` will add `program.log` to your application. The plugin will enable output to the terminal depending on the log level. The plugin will also add the `-d` option to your application to enable debug logging. Then logging can be done like this:
Adding `require('autocmdr/lib/logger')(program)` will add `program.log` to your application. The plug-in will enable output to the terminal depending on the log level. The plug-in will also add the `-d` option to your application to enable debug logging. Then logging can be done like this:

program.log('info', 'Hello!');
program.info('Hello again');
program.debug('Can you hear me now?');

### config

This plugin will load [nconf](https://github.com/flatiron/nconf) for handeling of configuration. WIP
This plug-in will load [nconf](https://github.com/flatiron/nconf) for handling of configuration. It will add program.config as an instance of nconf.

Adding `require('autocmdr/lib/config.js')(program)` will enable this.
Adding `require('autocmdr/lib/config')(program)` will enable this.

### help

This plugin will use [didyoumean](https://github.com/dcporter/didyoumean.js) to add a "Did you mean:" message to your application when an unknown command is given.
This plug-in will use [didyoumean](https://github.com/dcporter/didyoumean.js) to add a "Did you mean:" message to your application when an unknown command is given.

Adding `require('autocmdr/lib/help.js')(program)` will enable this.
Adding `require('autocmdr/lib/help')(program)` will enable this.

### package

This plugin will use the will load resonable defaults (such as descrtion and bug reporting url) from your application's package.json.
This plug-in will use the will load reasonable defaults (such as description and bug reporting URL) from your application's package.json.

Adding `require('autocmdr/lib/package.js')(program)` will load the package.json file located one directory above the executable. You can override this path using the options object.
Adding `require('autocmdr/lib/package')(program)` will load the package.json file located one directory above the executable. You can override this path using the options object.

### completion

This pluging will use [node-tabtab](https://github.com/mklabs/node-tabtab) to add auto-completion support to your application.
This plug-in will use [node-tabtab](https://github.com/mklabs/node-tabtab) to add auto-completion support to your application.

Adding `require('autocmdr/lib/completion.js')(program)` just before `program.parse(argv);` will will enable auto-completion support. You will then need to do one of the following to enable auto-completion in your shell.
Adding `require('autocmdr/lib/completion')(program)` just before `program.parse(argv);` will will enable auto-completion support. You will then need to do one of the following to enable auto-completion in your shell.

* Add completion helper to ~/.bashrc (or ~/.zshrc) `pkgname completion >> ~/.bashrc`
* Add completion to current shell `. <(pkgname completion)`

### prompt
`var prompt = require('autocmdr/lib/prompt')(program)`

### render
`var render = require('autocmdr/lib/render')(program)`

# Questions

Q: Doesn't flatiron do the same thing? You're even using some flatiron modules! Why not just use [flatiron](https://github.com/flatiron/flatiron) to build your cli applications.

A: Good question with perhaps a few bad answers.
A: Good question with perhaps a few bad answers. Basically it boils down to a few core design choices.

1. Flatiron uses [broadway](https://github.com/flatiron/broadway) for plugins. This feels very much like a web framework thing. Honestly, when I first encountered flatiron (before starting to work on autocmdr) I didn't even realize that it had cli support, and after looking at it more later I realized it's cli support was good but still felt like an afterthought.
2. Flatiron uses [optimist](https://github.com/substack/node-optimist) for command line parsing. I felt commander.js was a cleaner api so I build autocmdr using that.
3. I really like the idea that I can prototype a command line app using autocmdr in local mode before creating a full app. Flatiron itself cannot do this but I'm sure it would be easy enough to build flatiron based tool that does.
4. Flatiron has a team working on their framework. Autocmdr is just me. I work on it in my spare time often late at night. I do this because I enjoy it.
- Autocmdr is just for cli applications (for what it's worth).
- I started working on autocmdr before I realized that flatiron it had cli scaffolding support. As I developed autocmdr I realized more and more how good flatiron was. Only issue I had was it's choice of core support modules.
- Flatiron uses [optimist](https://github.com/substack/node-optimist) for command line parsing. I felt commander.js was a cleaner api so I build autocmdr using that.
- I haven't quite bought [Broadway](https://github.com/flatiron/broadway)'s' for plug-in definitions. That could change. I like that autocmdr's plug-ins and command files are essentially the same things.
- I really like the idea that I can prototype a command line app using autocmdr in local mode before creating a full app. Flatiron itself cannot do this but I'm sure it would be easy enough to build flatiron based tool that does. Also, scaffolding a command is not yet available in flatiron.
- Flatiron has a team working on their framework. Autocmdr is just me. I work on it in my spare time often late at night. I do this because I enjoy it.

# Share

Expand All @@ -247,4 +264,4 @@ See [todo.md](https://github.com/Hypercubed/autocmdr/blob/master/todo.md) \( man

autocmdr itself was (partially) built using [autocmdr](https://github.com/Hypercubed/autocmdr).

autocmdr is build on top of [commander.js](https://github.com/visionmedia/commander.js) and inspired by other task managers \( [grunt](https://github.com/gruntjs/grunt), [automaton](https://github.com/IndigoUnited/automaton) \) and command line tools \( [docpad](https://github.com/bevry/docpad), [git](https://github.com/git/git) \).
autocmdr is build on top of [commander.js](https://github.com/visionmedia/commander.js) and inspired by other task managers \( [grunt](https://github.com/gruntjs/grunt), [automaton](https://github.com/IndigoUnited/automaton) \) and command line tools \( [docpad](https://github.com/bevry/docpad), [git](https://github.com/git/git) \) and (of course) [flatiron](https://github.com/flatiron/flatiron).

0 comments on commit b5515bf

Please sign in to comment.