Sonntag, 19. Oktober 2014

Create a simple Ruby rake task!

Some times simple tasks around the application need to be done. They are not a primary part, but belong to the application. Those tasks are called automated tasks (e.g. automated built system). Rake is such task system based on the make file idea, but scripted in Ruby.
A really simple rake task skeleton in lib/tasks/test.rake looks like:
namespace :awesome do
  desc "Awesome Ruby does awesome things."
  task :ruby do |t| 
    puts "Ruby is awesome!"
  end 
end
and only consists of a task and its description. It can be listed with:
rake -T | grep ruby
=> rake awesome:ruby   # Awesome Ruby does awesome things.
Calling it in bash:
rake awesome:ruby
=> Ruby is awesome!
A little more reasonable rake task could be an automated version system merge of a branch back into the trunk.
Assuming GIT was set up with those configurations:
git config user.name "trinibago"
git config --global credential.helper /usr/share/doc/git/contrib/credential/gnome-keyring/git-credential-gnome-keyring
git config --global push.default current
which configures my github user name, my credentials for the account (prevents account prompts) and the current checked out branch to be the one to push to remotely.
The git rake task in lib/tasks/git.rake:
namespace :git do
  desc "GIT merges branch back into master"
  task :merge, :message do |t, args|
    safe_task do
      branches = %x[git branch]
      current_branch = branches.split("\n").map(&:strip).
        detect { |x| x.match(/^*\s/) }.gsub(/^[*]\s/, '') 
      %x[git commit -a -m "#{args[:message]}"]
      # pushes the current branch changes to the remote
      %x[git push]
      # switches back to master
      %x[git checkout master]
      # merges the current branch
      %x[git merge "#{current_branch}"]
      # pushes the merged mater changes to the remote
      %x[git push]
    end 
  end 
end

private
  def safe_task
    yield
  rescue Errno::ENOENT => e
    puts "Task couldn't be executed.\n#{e.message}"
  end 
demands some explanation.
  1. all parameters are listed in args as a hash
  2. other Ruby functions can be called (like the safe_task, which wraps the exception handling)
  3. %x literal is a Ruby system call (read Tell shell scripting apart in Ruby!)
  4. the result of 'git branch' is parsed for getting the current branch name
  5. simple git commands processed sequentially
In console the task can be invoked by:
rake git:merge["Hottest fix ever"]
=> Counting objects: 13, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 417 bytes | 0 bytes/s, done.
Total 5 (delta 4), reused 0 (delta 0)
To https://github.com/trinibago/nested_set
 * [new branch]      hotfix -> hotfix
Switched to branch 'master'
Everything up-to-date
Rake tasks can be simple helper tools in daily life and also are combinable.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.19