require 'rake'
require 'chrysalis/loader'
# Intercept Rake's methods for declaring tasks.
#
# Task interception is used to construct internal tables, and synthesize
# tasks in the all: namespace.
#
# Tasks declared in the course of loading a dependency are intercepted
# completely, and are unknown to Rake. This prevents dependencies from
# polluting the task space of their dependents.
#
# Tasks declared by the main rakefile are forwarded to Rake's original methods,
# ensuring that the system remains consistent.
class Object
alias_method :rake_task, :task
def task(args, &block)
task_name, deps = Rake.application.resolve_args(args)
Chrysalis::Loader.instance.task_intercept(task_name) { rake_task(args, &block) }
end
alias_method :rake_file, :file
def file(args, &block)
task_name, deps = Rake.application.resolve_args(args)
Chrysalis::Loader.instance.file_task_intercept(task_name) { rake_file(args, &block) }
end
alias_method :rake_file_create, :file_create
def file_create(args, &block)
task_name, deps = Rake.application.resolve_args(args)
Chrysalis::Loader.instance.file_task_intercept(task_name) { rake_file_create(args, &block) }
end
#--
# NOTE: Intercepting directory tasks is unnecessary, because Rake itself
# implements them as a set of file_create tasks. Thus, the interception
# of file_create is sufficient.
#alias_method :rake_directory, :directory
#def directory(dir)
#end
alias_method :rake_multitask, :multitask
def multitask(args, &block)
task_name, deps = Rake.application.resolve_args(args)
Chrysalis::Loader.instance.task_intercept(task_name) { rake_multitask(args, &block) }
end
alias_method :rake_namespace, :namespace
def namespace(name=nil, &block)
Chrysalis::Loader.instance.namespace_intercept(name, block) { rake_namespace(name, &block) }
end
alias_method :rake_rule, :rule
def rule(args, &block)
Chrysalis::Loader.instance.rule_intercept { rake_rule(args, &block) }
end
alias_method :rake_desc, :desc
def desc(comment)
Chrysalis::Loader.instance.desc_intercept(comment) { rake_desc(comment) }
end
end
module Rake
class Application
alias_method :rake_top_level, :top_level
# Invoked after the main rakefile has been loaded, but before any tasks are
# executed.
#
# Chrysalis reimplements this method for the purpose of hooking into the
# loader and seeding the all: namespace with tasks, prior to
# retrieval of dependencies.
#
# After invoking the hook, execution proceeds with Rake's original method.
def top_level
Chrysalis.post :rakefile_loaded
rake_top_level
end
end
end