## Description

Boson is a modular command/task framework. Thanks to its rich set of plugins,
it differentiates itself from rake and thor by being usable from irb and the
commandline, having automated views generated by hirb and allowing libraries to
be written as plain ruby. Works with on all major rubies for ruby >= 1.9.2

## New Boson

Starting with 1.0, boson has changed significantly. Please read [the upgrading
doc](http://rdoc.info/gems/boson/file/Upgrading.md) if you have an older version
or if your [reading about boson](http://tagaholic.me/blog.html#gem:name=boson)
predates 2012.

Boson has been rewritten to have a smaller core (no dependencies) with optional
plugins to hook into its various features. The major focus of 1.0 has been to
provide an easy way for third-party gems to create their executable and define
subcommands with options.

## Docs

Nicely formatted docs are available
[here](http://rdoc.info/gems/boson/file/README.md).

## Example Executable

For a gem with an executable, bin/cow:

```ruby
#!/usr/bin/env ruby
require 'boson/runner'

class CowRunner < Boson::Runner
  option :urgent, type: :boolean
  def say(text, options={})
    text.capitalize! if options[:urgent]
    puts text
  end

  def moo
    puts "MOOOO"
  end
end

CowRunner.start
```

You can now execute cow with say and moo subcommands:

    $ cow say hungry
    hungry
    $ cow moo
    MOOOO
    # use say's urgent option
    $ cow say hungry -urgent
    HUNGRY

You'll notice that this syntax is powerful and concise and is very similar to
thor's API. Subcommands map to ruby methods and the class represents the executable.

## Comparison to Thor

Since boson and it's rewrite are both heavily inspired by [thor](http://github.com/wycats/thor), it
makes sense to compare them.

First, what I consider pros boson has over thor. Boson

* is designed to handle plugins. This means it core parts are extendable by
  modules and core components like commands can have arbitrary metadata
  associated with them.
* has a rich set of plugins. See [boson-more](http://github.com/cldwalker/boson-more).
* has commands that are easily testable. Whereas thor has options that automagically
  appear in command methods, boson explicitly passes options to its command
  method as a hash i.e. `MyRunner.new.subcommand(arg, verbose: true)`. This
  also allows commands to just be called as ruby, with no magic to consider.
* supports custom-user option types i.e. creating a Date option type. See
  Boson::Options.
* supports custom method decorators i.e. methods like desc that add functionality
  to a command. While boson supports option, options, desc and config out of the box,
  users can create their own.
* automatically creates usage for your subcommand. With thor you need to
  manually define your usage with desc: `desc "SOME USAGE", "SOME DESCRIPTION"`
* is lenient about descriptions. Describe commands at your leisure. With thor
  you must define a desc.
* has a smaller blacklist for command names i.e. just Kernel + Object method
  names. Thor has a bigger
  [blacklist](https://github.com/wycats/thor/blob/a24b6697a37d9bc0c0ea94ef9bf2cdbb33b8abb9/lib/thor/base.rb#L18-19) due to its design.

Now for pros thor has over boson. Thor

* is widely used and thus has been community QAed thoroughly.
* supports generators as a major feature.
* is more stable as its feature set is mostly frozen.
* is used by rails and thus is guaranteed support for some time.
* supports ruby 1.8.7.
* TODO: I'm sure there's more

## Writing Plugins

The most common way to write a plugin is to extend one of the many method hooks
available. Any methods that are defined in an API or APIClassMethods module
are extendable. For example, if you want to extend what any boson-based
executable does first, extend BareRunner.start:

```ruby
module CustomStartUp
  def start(*)
    super
    # additional startup
  end
end

BareRunner.extend CustomStartUp
```

Notice that `extend` was used to extend a class method. To extend an instance
method you would use `include`. Also notice that you use `super` in an
overridden method to call original functionality. If you don't, you're
possibly overridden existing functionality, which is fine as long as you know
what you are overriding.

For many plugin examples, see
[boson-more](http://github.com/cldwalker/boson-more).

## Bugs/Issues

Please report them [on github](http://github.com/cldwalker/boson/issues).
If the issue is about upgrading from old boson, please file it in
[boson-more](http://github.com/cldwalker/boson-more/issues).

## Contributing
[See here](http://tagaholic.me/contributing.html)

## Motiviation

Motivation for the new boson is all the damn executables I'm making.

## Credits
Boson stands on the shoulders of these people and their ideas:

* Contributors: @mirell, @martinos
* Yehuda Katz for Thor and its awesome option parser (Boson::OptionParser).
* Daniel Berger for his original work on thor's option parser.
* Chris Wanstrath for inspiring Boson's libraries with Rip's packages.