Finding Bugs with Git Bisect

October 13th, 2009 Jeremy Olliver No comments

If you’ve ever had a bug that got introduced to an application you’re working on at some point, but haven’t been able to track down what caused it, then git has a really useful feature that you can use to track it down called bisect.

This happened to Jordan Daniel Carter and I recently. We had a bug to do with the javascript interface and some values not being inserted into a form correctly. These kind of bugs can sometimes be hard to track down, because they can be affected by either changes to the javascript, or the html is manipulates. We came across the bisect function in a google search, and decided to give it a go, the process is pretty simple

# First create a local branch to do the tracking in
git checkout -b find_that_bug
# Next, start bisecting!
git bisect start

After that, you need to mark some commits or references that you know either contain or don’t contain the bug. In our case we know that the bug currently exists in master, so we github commits to find one old enough that we were sure wouldn’t have the bug.

# the master branch is broken
git bisect bad master
# but this commit is good
git bisect good 0f54590e

This is where it starts to get fun. We were initially confused because we expected the next part to take a linear approach, but it wasn’t. Git tells you how many commits are between the two,  that’s the number of commits left to check, (if they were the ones to introduce the bug). Then git will load up a commit somewhere in between and you mark it as either good or bad, depending if it’s got the bug checking either the unit tests, or in our case actually using the web interface. The smart thing is that it zips back and forwards between the good and bad end, zeroing in on the commit that introduced the bug, so you may only end up checking around 6 commits out of 40.

Once the “original bad commit” is found, git places you at the commit just before that, and you can look at the diff for what was changed in the bad commit, and try applying some of those changes if necessary to see exactly what it was that broke your code. In our case the offending change was something as innocuous as adding an extra closing div tag to a partial that was misleadingly enough not self contained, and the div wasn’t supposed to be closed.

All in all, we were pretty happy to have found the bug so quickly, and found git bisect incredibly useful. Seeing how useful it was made highlighted for me the necessity of self contained commits (e.g. when refactoring, commit the entire refactor. Don’t break something, commit, then fix it in a later commit if you can help it) because this will prevent you being able to find bugs for that feature with git bisect.

Categories: git Tags: , ,

Utilizing the Google Visualization API with Ruby on Rails

August 30th, 2009 Jeremy Olliver 2 comments

If you haven’t seen it yet, Google have recently released a public visualization API for generating many different types of graphs including Geo Map, and Motion Charts. The graphs are all in the nice clean style that you see in Google Analytics. The end result of the graphs is really nice, and is produced with nothing more than javascript, however anyone utilizing a framework for dynamic Web applications will likely want a more developer friendly way to embed the data.

For those of you using Ruby on Rails, I’ve written a plugin gvis that makes the syntax for embedding data a lot cleaner, and most of all, accepts ruby data arrays, handling the library loading and javascript data formatting for you. As an example to see how easy this is, lets go through setting up a new rails application and drawing a graph with this plugin.

rails graphapp
cd graphapp
script/plugin install git://github.com/jeremyolliver/gvis.git
# note you'll need git installed for the above line to work.

Now lets add a single controller and add routes for it.

script/generate controller home

# config/routes.rb
map.resources :home

# include the plugin module in application helper
# so that we can add a graph anywhere in our app

# app/helpers/application_helper.rb
include GoogleVisualization

# Lets add a simple layout, it need only include google's javascript
# source for the visualization api, and then call render_visualizations

# app/views/layouts/application.html.erb
<html>
  <head>
    <title>Test app</title>
    <%= include_visualization_api %>
    <%= render_visualizations %>
    <%= yield :head %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

Now lets render a nice fancy MotionChart on our home page.

# app/views/home/index.html.erb
<h1>Rendering a cool MotionChart</h1>

<%# This data would typically be pulled from the database,
    but lets just put some sample data into an array %>
<% chart_data = [
   ["Apples", Date.new(1998,1,1), 1000,300,'East'],
   ["Oranges", Date.new(1998,1,1), 950,200,'West'],
   ["Bananas", Date.new(1998,1,1), 300,250,'West'],
   ["Apples", Date.new(1998,2,1), 1200,400,'East'],
   ["Oranges", Date.new(1998,2,1), 950,150,'West'],
   ["Bananas", Date.new(1998,2,1), 788,617,'West']
 ] %>

<% visualization "chart_id", "MotionChart", :width => 600, :height => 400,
                             :html => {:class => "graph_class"} do |chart| %>
 <% chart.string "Fruit" %>
 <% chart.date "Date" %>
 <% chart.number "Sales" %>
 <% chart.number "Expenses" %>
 <% chart.string "Location" %>

 <% chart.add_rows(chart_data) %>
<% end %>

And Vóila! we now have a beautiful Motion Chart displayed in our rails app in almost no time. Let me know if you find this useful, or you have any thoughts on how this could be improved.

Categories: Rails Tags: , , ,

Using MacRuby to write a .qif file converter

August 19th, 2009 Jeremy Olliver No comments

I heard about the MacRuby project not too long ago and was quite excited about it for several reasons, the first is  that although it’s early days yet and version 0.4 doesn’t cover the full ruby spec, it’s showing signs of being a well performing ruby implementation. Others have already gone into significant detail about the differences, but to summarise: The original ruby implementation isn’t the best at memory management for long running processes, and this is the most recent of several other implementations that provide better performance. The other reason to get excited about this is that because MacRuby is essentially the ruby language written in Objective-C (not just a bridge), it means you can utilise both ruby’s syntactical sugar and the Cocoa library to write native Mac OS X applications using ruby code. This is pretty cool to me, because Objective-C has a pretty verbose syntax, manual memory allocation, and is generally not quite as pretty to read and write as ruby code.

Of course, nothing illustrates this quite as well as seeing how short a sample (trivial) GUI program is when written with MacRuby and HotCocoa:

require 'hotcocoa'
include HotCocoa
application do |app|
  window :size => [100, 50] do |win|
    b = button :title => 'Hello'
    b.on_action { puts 'World!' }
    win << b
  end
end

The equivalent code in Objective-C is about 3 times as long, less readable and much more confusing. That’s what I love about well written ruby code: It should be clear what’s happening, and straight to the point.

I couldn’t wait to try out writing a desktop app with MacRuby, so when Megan Christiansen was doing some work needing some financial data converted from .qif format to .csv we had a look for a free tool to do this on Mac OS X, but we couldn’t find one that fit the bill. So after utilising a bit of regex magic to convert the files, I decided to test out just how easy it was to write a desktop app in MacRuby, by writing an app with a GUI to do the file conversion process.

After trying out using XCode to create a new MacRuby project without much luck, I found that the HotCocoa library that comes with MacRuby (0.3+) can generate a blank app for you. Once MacRuby is installed (I’m using version 0.4) you can simply type

 hotcocoa myapp

from the terminal to generate a new application, with some laid out code, just waiting for you to add the visual elements and logic you need to your app. This sets up some rake tasks for compiling the application too using macrake (MacRuby’s binaries are just like you’re used to but prefixed with mac, macruby, macrake, macgem etc) including for when your application is finished, you can package up the MacRuby framework inside the final application for distribution, so that others can run your .app file without having to have MacRuby installed on their computer.

cd myapp
macrake        # This builds and launches the .app
macrake deploy # This builds a fully packaged version ready to ship

Overall, the process was pretty simple, I added some horizontal and vertical layouts to configure the window looked, and after only a few days of reading the documentation and coding in my spare time, I came up with Qif2csv. It’s a bit rough, and I still didn’t figure out how to make a check box with the ruby syntax, though feel free to download it, and browse the source. It was fun to try out something a bit different, and it’s always good to keep building new skills. Now of course, we can all anticipate the release of MacRuby 0.5 which is a largely performance focused release, and I believe will also support native threading.

Categories: Ruby Tags: , , , ,

Git branch shown in command prompt

July 21st, 2009 Jeremy Olliver No comments

I’ve been using git for source control for a while now, and I’m really enjoying using a distributed system over the conventional server-client system like svn. A distributed versioning system is somewhat conceptually different in the way that is works, and while it’s worth taking the time to understand the differences, one of the immediate differences is in the way branches are stored in the file-system. With a traditional system, checking out a branch of your code involves creating a whole new folder for your local checkout, duplicating a whole lot unnecessarily, though it is pretty obvious what’s going on.

In contrast when you are using git, your local computer has it’s own entire repository (hence distributed), this is stored in a hidden folder inside the project root (myproject/.git/). When you checkout a new branch, the files in the project directory are updated in place with the files from the branch. This means that multiple branches all reside within the same folder on your computer, and only one can be checked out at a time, it can get somewhat confusing at times to remeber which branch is currently checked out, and it’s annoying having to type “git branch” every time you want to find out. Here’s a bash script that displays which git branch is currently checked out whenever your terminal is residing in a git repository.

~/projects/myproject(master) $

Simply add the following code to ~/.bash_profile (create it if it doesn’t exist), and you’ll always know which git branch you currently have checked out.

# ~/.bash_profile
parse_git_branch() {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
PS1="\w\$(parse_git_branch) $ "
Categories: git Tags: , , ,

Custom Change Messages – Rails Plugin

July 18th, 2009 Jeremy Olliver No comments

While working on some code maintenance for PlanHQ I noticed a prime opportunity to refactor some code in the spirit of keeping the code DRY. There was code in both the controller action and in mailer methods that created a short paragraph of text describing what fields had been edited on several models for the purposes of both logging this for users to reference later, and to send email notifications.

My solution for this problem was to create this plugin (code available on github) which extends ActiveRecord::Base to provide a few simple methods on instances of your models to generate this text summary of the changes, before the model is saved back to the database (taking advantage of the code in the ActiveRecord::Dirty module). The plugin provides an easy way to customise the messages that are displayed and their format, and handles belongs_to associations nicely as well: Given a Task model that belongs_to a User model, re-assigning a task would produce the message “user has been changed from ‘Jeremy’ to ‘Jordan’” rather than the less informative “user_id has changed from 1 to 2″. See the README for more details on usage.

Usage: see the README for more

# Item.rb
class Item < ActiveRecord::Base
  belongs_to :person

  custom_message_for :person, :display => :username
  custom_message_for :due_on, :as => "Due Date",
  :message => "has been rescheduled", :format => :pretty_print_date

  # this method is used for formatting the due_on field when it changes
  def pretty_print_date(value = self.due_on)
    value.strftime("%d/%m/%Y")
  end
end
# ItemsController.rb
class ItemsController < ApplicationController

  def update
    @item.attributes = params[:item]
    Mailer.deliver_item_update(@item, @item.change_messages.to_sentence)
    @item.save!
  end

end
Categories: Rails Tags: , , , ,