RakeCommander

Classing rake tasks with options. Creating re-usable tasks, options and samples thereof.

Introduction

Rake commander is a way to declare rake tasks with re-usable classes. It enhances the command line syntax, as tasks can come with their own options, inherit them, re-use declared options sets, modify/re-open or even remove them.

Although the OptionParser ruby native class is used for parsing the options, the declaration of options, additionally to the ones of OptionParser comes with some opinionated improvements and amendments:

  1. It is possible to declare options as required
    • This is additional to required option arguments.
    • Options are inheritable (they get a custom deep_dup)
  2. An option can have a default value.
    • Which can optionally be automatically used when the option accepts or requires an argument.
  3. Options parsing raises specific option errors. For a given task/class, each error type can have its own handler or preferred action.
    • Defined error handling is inheritable and can be redefined.

Installation

Add this line to your application's Gemfile:

gem 'rake-commander', require: %w[rake-commander]

And then execute:

$ bundle

Or install it yourself as:

$ gem install rake-commander

Changelog

See CHANGELOG for a list of changes.

Usage

See the examples.

rake -T examples

Go through the basic example.

rake examples:basic -- -h
rake examples:basic -- -z -e prod
  • The double dash -- is used to tell to rake-commander where the options section starts.

At the same time the double dash delimiter seems to make rake ignore anything that comes afterwards. Without loading rake commander, you could try:

$ rake --trace rspec
** Invoke spec (first_time)
** Execute spec
rspec logging and results

And then re-try with

$ rake rspec -- --trace
rspec logging and results
  • The --trace option is being natively ignored by rake due to the preceding double dash (--).

Syntax

RakeCommander::Custom::Base < RakeCommander
  include Rake::DSL
end
  • include Rake::DSL for backwards compatibility
RakeCommander::Custom::MyTask < RakeCommander::Custom::Base
  desc "it does some stuff"
  task :do_stuff

  option :s, '--do-stuff [SOMETHING]', default: 'nothing'

  def task(*_args)
    puts "Doing #{options[:s]}" if options[:s]
  end
end

Declaring and using Task Options

It supports most of options syntax of the native OptionParser but for a couple of exceptions perhaps:

  1. It does NOT support definitions or parsing of shortcuts with embedded argument (i.e. -nNAME).
  2. It does NOT support definitions that include equal sign (i.e. name=NAME, n=NAME)
  3. Currently, declaring a short and a name for the option is compulsory.

An argument of an option should be explicitly declared in the name part:

  option :n, '--name NAME'

Command Line

Although it is planned to extend the syntax, the current version shares the options through all tasks (declared as RakeCommander classes) that are invoked in the same command line.

rake [rake-options] task1 task2 -- [shared-task-options]

The double dash -- delimiter allows to modify the ARGV parsing behaviour of rake, giving room for opinionated enhanced syntax. Anything that comes before the double dash is fed to standard rake, and anything after -- are parsed as option tasks via rake commander.

<rake part> -- [tasks options part]

rake full support

Work has been done with the aim of providing a full patch on rake, provided that the main invocation command remains as rake.

Patching Rake

There is only one patch onto Rake::Application#top_level method, collect_command_line_tasks is recalled with the arguments cut (so it does not interpret task option arguments as tasks).

For further details please see RakeCommander::Patcher.

Development

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

For more info on available Rake tasks: rake -T (or bin/raked -T)