Custom Tasks

jbuedel edited this page Nov 10, 2011 · 11 revisions

It’s now easier than ever to create your own tasks that take advantage of the Albacore infrastructure.

Custom Tasks

To create your own task, you need to do a few things in a standard ruby class:

  • “include Albacore::Task”. this module will bring most of the albacore functionality into your class and it will create a custom rake task for you, using the name of your class.
  • a no-args initializer. all albacore task classes need to have an initializer that can be run with no parameters. you can allow optional parameters if you want.
  • an execute method. all albacore task classes need to have an execute method – again, with no parameters – so that the task can call .execute on your class
class MySuperAwesomeTask
  include Albacore::Task
  def execute
    # step 1: set up the task like this
    # step 2: ???
    # step 3: profit!
  end
end

For example, to create a replacement for the now-deleted ExpandTemplates task, using ERB as the template system, the following code can be used:

ERB docs

require 'erb'

class ExpandTemplate
  module GetBinding
    def get_binding
      binding
    end
  end

  include Albacore::Task

  attr_accessor :template, :output
  attr_hash :settings

  def execute
    expand_template(@template, @output, @settings)
  end

  def expand_template(template_file, output_file, settings)
    template = File.read template_file

    vars = OpenStruct.new(settings)
    vars.extend GetBinding
    vars_binding = vars.get_binding

    erb = ERB.new template
    output = erb.result(vars_binding)

    File.open(output_file, "w") do |file|
      puts "Generating #{file.path}"
      file.write(output)
    end
  end
end

The inclusion of “Albacore::Task” on line 9 will automatically create an “expandtemplate” task for you. You can then call the task like any other albacore or other rake task:

expandtemplate :appconfig do |tmp|
  tmp.template = "templates/app.config.template"
  tmp.output = Files[:output] + ".config"
  tmp.settings( 
    :mysetting => "this is some settings",
    :connectionstring => "some connection string"
  )
end

To see this example in action, take a look at the vimbacore project on github. It is my playground where I test out a lot of the new features and functionality of albacore, and I’ve included this (and a config example) in that project.

Using your custom task

To use your custom task you must either include the task’s class directly in your rakefile or define it in a separate file and “require” it like so:

require 'ExpandTemplate.rb'

If you have several individual files to include you can do something like this:

FileList["./albacore/**/*.rb"].each { |f| require f }

Command-line Tools

Albacore makes it easy to provide the needed code to call a command-line as well. In addition to the Albacore::Task module, include the Albacore::RunCommand module in your class. This module gives you the .command and .parameters attributes, as well as the runcommand method.

The .runcommand method takes a few parameters:

  • A string for the name of the tool being executed (not the .exe or other file name, but the tool’s name. For example “C-Sharp Compiler” or “My Unit Test Tool”).
  • A string for all of the parameters to pass to the command-line tool. For example: “/file=myfile.xml /output=myfile.html”

You do not need to provide the path to the executable or command-line tool itself because this is captured in the .command attribute.

As an example, if you wanted to create a task that executed a tool called “foo.exe” with a “/file” parameter, you could create a task like this:

class Foo
  include Albacore::Task
  include Albacore::RunCommand

  attr_accessor :file

  def execute
    run_command "Foo Bar Tool", "/file=#{file}"
  end
end

You can then run this task from your rakefile as any other task.

Custom Task Names

There are times when you want to name a task’s class one thing, but you want to have the task method (the method that you call in your rakefile) named something else. An example of this in albacore is the “nunit” task. The class that runs and defines this task is actually called NunitTestRunner. To avoid having tasks with long, ugly names like that, you can specify one (or more) task method names in your class by specifying a “TaskName” constant prior to the “include Albacore::Task” line in your class. Here’s how the NunitTestRunner class is defined:

class NUnitTestRunner
  TaskName = :nunit
  include Albacore::Task
  # ...
end

The use of “TaskName = :nunit” instructs albacore to create the task method “nunit” instead of “nunittestrunner”. You can also specify multiple names if you want aliases for your task:

class MyCustomTask
  TaskName = [:task1, :task2, :taskN]
  include Albacore::Task
end

This will create 3 task methods that you can use from your rakefile: task1, task2 and taskN.

task1 :foo do |t|
  # ...
end

task2 :bar do |t|
  # ...
end

taskN :baz do |t|
 # ...
end

Custom Configuration

The Albacore.configure block also support plug-in capabilities. All you need to do is create a ruby module that includes “Albacore::Configuration” and your module will automatically become part of the Albacore.configure block. Here’s an example that doesn’t really do much (again, this example is in my vimbacore project) but illustrates how simple it is:

module ExpandTemplateConfig
  include Albacore::Configuration
 
  def expandtemplate
    puts "..........Albacore.configure.expandtemplate was called. This is a demonstration of the configuration plugin system.\r\n\r\n"
  end
end

You can then call .expandtemplate in the Albacore.configure block:

Albacore.configure do |config|
  config.expandtemplate
end

This example doesn’t do much, but it does illustrate how simple it is to create a plugin for the configuration system.