1
votes

I have a number of rake tasks for which I would like to implement around-hook-like behavior. Specifically, I'm looking for a way to ensure that all of my Rake tasks execute in a particular (complicated, derived) Time.use_zone block.

For analogy, I have this in my ApplicationController:

around_filter :use_time_zone

def use_time_zone
  time_zone = non_trivial_derivation
  Time.use_zone(time_zone) { yield }
end

And now all of my controller actions will appropriately execute in the specified time zone. I would like some mechanism like this for Rake. I'd be willing to change or modify the dependency chain for my rake tasks, but I don't want to insert the actual time zone derivation code at the top of each rake task, out of concerns that that would lead to maintenance fragility. I'm pretty sure that Rake dependencies hold the solution--after all, Rake dependencies allow me to execute code in the context of my Rails application. But I can't figure out how to get that done for this use case.

1

1 Answers

2
votes

I came up with a simple solution that doesn't require any external dependencies or gems such as rake-hooks:

desc "rake around hook"
task :use_timezone, [:subtask] => :environment do |name, args|
  puts "using timezone"
  Rake::Task[args[:subtask]].invoke
  puts "end using timezone"
end

task :testing do
  puts "testing"
end

The idea is that you execute the main use_timezone task and pass in your actual task as an argument:

$ rake use_timezone[testing]

That outputs:

> using timezone
> testing
> end using timezone

For your case you can write it like this:

task :use_timezone, [:subtask] => :environment do |name, args|
  time_zone = non_trivial_derivation
  Time.use_zone(time_zone) { Rake::Task[args[:subtask]].invoke }
end

And use it like this:

$ rake use_timezone[your_task]

Hope that helps.