BuildSourceBuildRulebook

class Rulebook

Represents a collection of rules, organized by process name for fast lookup.

Definitions

def initialize(name = nil)

Initialize the rulebook.

Signature

parameter name String | Nil

An optional name for this rulebook.

Implementation

def initialize(name = nil)
	@name = name
	@rules = {}
	@processes = {}
end

def <<(rule)

Add a rule to this rulebook.

Signature

parameter rule Build::Rule

The rule to add.

Implementation

def << rule
	@rules[rule.name] = rule
	
	# A cache for fast process/file-type lookup:
	processes = @processes[rule.process_name] ||= []
	processes << rule
end

def [](name)

Look up a rule by its full name.

Signature

parameter name String

The rule name, e.g. "compile.cpp".

returns Build::Rule | Nil

The matching rule, or nil.

Implementation

def [] name
	@rules[name]
end

def with(superclass, **state)

Generate a task subclass with methods for all rules in this rulebook.

Signature

parameter superclass Class

The base task class to inherit from.

parameter state Hash

Additional state methods to define on the subclass.

returns Class

The generated task subclass.

Implementation

def with(superclass, **state)
	task_class = Class.new(superclass)
	
	# name = @name
	# task_class.send(:define_method, :to_s) do
	# 	"name"
	# end
	
	# Define methods for all processes, e.g. task_class#compile
	@processes.each do |key, rules|
		# Define general rules, which use rule applicability for disambiguation:
		task_class.send(:define_method, key) do |arguments, &block|
			rule = rules.find{|rule| rule.applicable? arguments}
			
			if rule
				invoke_rule(rule, arguments, &block)
			else
				raise NoApplicableRule.new(key, arguments)
			end
		end
	end
	
	# Define methods for all rules, e.g. task_class#compile_cpp
	@rules.each do |key, rule|
		task_class.send(:define_method, rule.full_name) do |arguments, &block|
			invoke_rule(rule, arguments, &block)
		end
	end
	
	# Typically, this defines methods like #environment and #target which can be accessed in the build rule.
	state.each do |key, value|
		task_class.send(:define_method, key) do
			value
		end
	end
	
	return task_class
end

def self.for(environment)

Build a rulebook from all rule definitions in the given environment.

Signature

parameter environment Build::Environment

The environment to extract rules from.

returns Build::Rulebook

The populated rulebook.

Implementation

def self.for(environment)
	rulebook = self.new(environment.name)
	
	environment.defined.each do |name, define|
		rulebook << define.klass.build(name, &define.block)
	end
	
	return rulebook
end