module Buildr::Extension
The basic mechanism for extending projects in Buildr are Ruby modules. In fact, base features like compiling and testing are all developed in the form of modules, and then added to the core Project class.
A module defines instance methods that are then mixed into the project and become instance methods of the project. There are two general ways for extending projects. You can extend all projects by including the module in Project:
class Project include MyExtension end
You can also extend a given project instance and only that instance by extending it with the module:
define 'foo' do extend MyExtension end
Some extensions require tighter integration with the project, specifically for setting up tasks and properties, or for configuring tasks based on the project definition. You can do that by adding callbacks to the process.
The easiest way to add callbacks is by incorporating the Extension module in your own extension, and using the various class methods to define callback behavior:
-
first_time – This block will be called once for any particular extension.
You can use this to setup top-level and local tasks.
-
before_define – This block is called once for the project with the project
instance, right before running the project definition. You can use this to add tasks and set properties that will be used in the project definition.
-
after_define – This block is called once for the project with the project
instance, right after running the project definition. You can use this to do any post-processing that depends on the project definition.
This example illustrates how to write a simple extension:
module LinesOfCode include Extension first_time do # Define task not specific to any projet. desc 'Count lines of code in current project' Project.local_task('loc') end before_define do |project| # Define the loc task for this particular project. Rake::Task.define_task 'loc' do |task| lines = task.prerequisites.map { |path| Dir['#{path} /*'] }.flatten.uniq. inject(0) { |total, file| total + File.readlines(file).count } puts "Project #{project.name} has #{lines} lines of code" end end after_define do |project| # Now that we know all the source directories, add them. task('loc'=>compile.sources + compile.test.sources) end # To use this method in your project: # loc path_1, path_2 def loc(*paths) task('loc'=>paths) end end class Buildr::Project include LinesOfCode end