= Methadone - kick the bash habit and start your command line apps off right
Author:: Dave Copeland (mailto:davetron5000 at g mail dot com)
Copyright:: Copyright (c) 2011 by Dave Copeland
License:: Distributes under the Apache License, see LICENSE.txt in the source distro
A smattering of tools to make your command-line apps easily awesome; kick the bash habit without sacrificing any of the power.
Currently, this is under development and has the following to offer:
* Bootstrapping a new CLI app
* Utility Classes
* Methadone::CLILogger - a logger subclass that sends error message to standard error and all messages to standard out
* Methadone::CLILogging - a module that, when included in any class, provides easy access to a shared logger
* Cucumber Steps
== Links
* {Source on Github}[http://github.com/davetron5000/methadone]
* RDoc[http://rdoc.info/github/davetron5000/methadone/master/frames]
== Bootstrapping
The +methadone+ command-line app will bootstrap a new command-line app, setting up a proper gem structure, unit tests, and cucumber-based tests with aruba:
$ methadone --help
Usage: methadone [options] app_name
--force Overwrite files if they exist
$ methadone newgem
$ cd newgem
$ rake
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
1 scenario (1 passed)
3 steps (3 passed)
$ cat features/newgem.feature
Feature: My bootstrapped app kinda works
In order to get going on coding my awesome app
I want to have aruba and cucumber setup
So I don't have to do it myself
Scenario: App just runs
When I run `newgem --help`
Then the exit status should be 0
And the output should contain:
"""
Usage: newgem [options]
"""
Basically, this sets you up with all the boilerplate that you *should* be using to write a command-line app.
== Utility Classes
Currently, there are classes the assist in directing output logger-style to the right place; basically ensuring that errors go to +STDERR+ and everything else goes to +STDOUT+. All of this is, of course, configurable
=== Examples
==== Using STDOUT as a log, respecting STDERR
require 'methadone'
include Methadone::CLILogging
command = "rm -rf /tmp/*"
debug("About to run #{command}") # => goes only to STDOUT
if system(command)
info("Succesfully ran #{command}") # => goes only to STDOUT
else
error("There was a problem running #{command}") # => goes to STDOUT AND STDERR
end
==== Using a log file, but respecting STDERR
require 'methadone'
include Methadone::CLILogging
self.logger = CLILogger.new("logfile.txt")
command = "rm -rf /tmp/*"
debug("About to run #{command}") # => goes only to logfile.txt
if system(command)
info("Succesfully ran #{command}") # => goes only to logfile.txt
else
error("There was a problem running #{command}") # => goes to logfile.txt AND STDERR
end
== Cucumber Steps
Methadone uses aruba[http://www.github.com/cucumber/aruba] for BDD-style testing with cucumber. This library has some awesome steps, and methadone provides additional, more opinionated, steps.
=== Example
Here's an example from methadone's own tests:
Scenario: Help is properly documented
When I get help for "methadone"
Then the exit status should be 0
And the following options should be documented:
|--force|
And the banner should be present
And the banner should document that this app takes options
And the banner should document that this app's arguments are:
|app_name|required|
=== Steps Provided
* Run command_to_run --help using aruba
When I get help for "command_to_run"
* Make sure that each option shows up in the help and has *some* sort of documentation
Then the following options should be documented:
|--force|
|-x |
* Check an individual option for documentation:
Then the option "--force" should be documented
* Checks that the help has a proper usage banner
Then the banner should be present
* Checks that the usage banner indicates it takes options via [options]
Then the banner should document that this app takes options
* Checks that the app's usage banner documents that its arguments are args
Then the banner should document that this app's arguments are "args"
== What might be
* Support for running external commands easily, with full error checking
* Support for main method-style implementation
* Easy support for filtering the output of a command, e.g. File.open("ls|") Perl-style