Skip to content

Instantly share code, notes, and snippets.

@dsci
Last active February 2, 2016 07:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsci/81e6b1a365b642543ec4 to your computer and use it in GitHub Desktop.
Save dsci/81e6b1a365b642543ec4 to your computer and use it in GitHub Desktop.
Rake Tasks from classes
# Use instance methods of classes as Rake tasks:
#
# In a folder tasks, create your classes.
#
# class FooTask
# extend RakeDecorator
#
# task :numbers, desc: 'A funny task that prints out the first 10 numbers'
# def print_numbers_task
# puts (1..10).to_a.join(',')
# end
# end
#
require 'rake' unless defined?(Rake)
module RakeTasks
@@tasks = {}
module_function
def add_task(task)
task_class = task[:class].name
if tasks.key?(task_class)
tasks[task_class][:tasks] << task
else
tasks[task_class] = {
tasks: [task]
}
end
end
def tasks
@@tasks
end
end
module RakeDecorator
def task(name, *args)
@_task = name
@_desc = args.pop if args.last.is_a?(Hash)
@_args = args
end
def desc(description)
@_desc = {}; @_desc[:description] = description
end
def method_added(meth_name)
RakeTasks.add_task(build_task_config(meth_name))
%i(_task _args _desc).each { |ivar| instance_variable_set("@#{ivar}", nil) }
end
private def build_task_config(meth_name)
task = {
class: self,
caller: self.instance_method(meth_name),
task_name: @_task,
arguments: @_args
}
task[:description] = @_desc[:desc] || @desc if @_desc
task
end
end
def LoadTasks(dir_path)
Dir[dir_path].each do |file|
require file unless File.directory?(file)
end
RakeTasks.tasks.each_pair do |task_class,value|
tasks, instance = value[:tasks], Module.const_get(task_class).new
tasks.each do |task|
Rake.application.last_description = task[:description] if task[:description]
caller = task[:caller]
Rake::Task.define_task(task[:task_name], task[:arguments]) do |arg|
caller.bind(instance).call
end
end
end
end
dir_path = File.join(File.dirname(__FILE__), 'tasks', '**')
LoadTasks(dir_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment