Rake is the Ruby make system, it lets you write tasks using the Ruby language and is used in most Ruby projects.
I wanted to automate some development tasks and had to figure out a few patterns, thought I’d blog them for my own future reference and hopefully to be useful to someone else.
In general people pass variables on the command line to rake, something like:
$ ENVIRONMENT=production rake db::migrate |
This is ok if you know all the variables you can pass but sometimes it’s nice to support asking if something isn’t given:
def ask(prompt, env, default="") return ENV[env] if ENV.include?(env) print "#{prompt} (#{default}): " resp = STDIN.gets.chomp resp.empty? ? default : resp end task :do_something do what = ask("What should I do", "WHAT", "something") puts "Doing #{what}" end |
This will support running like:
$ WHAT="foo" rake do_something |
It will also though prompt for the information with a default if the environment variable isn’t set. The only real trick here is that you have to use STDIN.gets and not just gets. For added niceness you could use Highline to build the prompts but that’s an extra dependency.
Here is what it does if you don’t specify a environment var:
$ rake do_something (in /home/rip/temp) What should I do (something): test Doing test |
The second tip is about rendering templates, I am using the above ask method to ask a bunch of information from the user and then building a few templates based on that. So I am calling ERB a few times and wanted to write a helper.
def render_template(template, output, scope) tmpl = File.read(template) erb = ERB.new(tmpl, 0, "<>") File.open(output, "w") do |f| f.puts erb.result(scope) end end task :do_something do what = ask("What do you want to do", "WHAT", "something") render_template("simple.erb", "/tmp/output.txt", binding) end |
The template would just have:
Doing <%= what %> |
This is pretty standard stuff the only odd thing is the binding, it basically takes the current scope of the do_something task and passes it into the render_template method that then pass it along to the erb. This way your local variable – what in this case – is available as a local variable in the template.