#!/usr/bin/env ruby # 2008.10.03 # JD Huntington # Darell Fuhriman # shell script to assist in working with lighthouse and git # # requires lighthouse api ruby wrapper and git library # $ gem sources -a http://gems.github.com/ # $ gem install Caged-lighthouse-api $initialized = false $:.unshift( File.expand_path( File.dirname( __FILE__ ) ) ) require 'rubygems' require 'lighthouse' require 'tempfile' $config = nil module BugFixing module_function def usage STDERR.puts " A bug fixing workflow. Workflow: git checkout master bugflow start [do some work] bugflow fixed hack && ship bugflow shipped Usage: usage display this message open view the active ticket in your default browser [OSX only] start create a new branch based on bugid, and assigns to you fixed commits all tracked and untracked files with , appends lighthouse tags to set to fixed state and assigns to 'none' shipped deletes the current working branch " end def load! return if $initialized == true load_config Lighthouse.token = $config['token'] Lighthouse.account = $config['account'] $initialized = true end def load_config(directory='.') if File.expand_path(directory) == '/' STDERR.puts "Bugflow config [.bugflow.yml] not found!" raise RuntimeError, "Bugflow config [.bugflow.yml] not found!" end filename = File.expand_path(directory + '/.bugflow.yml') if File.exists?(filename) $config = YAML.load(File.read(filename)) else load_config(File.expand_path(directory + '/..')) end end def open load! url = "http://#{$config['account']}.lighthouseapp.com/projects/#{$config['project']}/tickets/#{find_current_ticket}" %x{open "#{url}"} end def fixed commit_msg=nil load! # %x{git add .} bug_info="[##{find_current_ticket} responsible:none state:#{$config['status']}]" if commit_msg.nil? require 'tempfile' tmp=Tempfile.new('commitmsg') tmp.puts bug_info tmp.close system "git commit -a -v -t #{tmp.path}" tmp.delete else commit_string = "#{commit_msg} #{bug_info}" puts %x{git commit -a -m '#{commit_string}'} end end def shipped current = find_current_branch %x{git checkout master} %x{git cherry master #{current}}.each do |line| add,commit=line.split(/\s+/) next unless add == '+' %x{git cherry-pick #{commit}} end %x{git branch -d #{current}} end def get_user_id load! Lighthouse::Token.find($config['token']).user_id end def find_current_branch output = %x{git branch} return output.grep(/^\*/).first.strip[2 .. -1] end def find_current_ticket branch = find_current_branch unless branch[0 .. 2] == 'bf-' STDERR.puts "Error - Not working on a bugflow branch" exit! end branch.split('-')[1].to_i end def start bug_id load! ticket = Lighthouse::Ticket.find(bug_id, :params => { :project_id => $config['project'] }) new_tagname = "bf-#{ticket.number}-#{ticket.permalink[0 .. 20]}" %x{git checkout -b #{new_tagname}} puts '' puts "Now working on ticket #{ticket.number} \"#{ticket.title}\" (#{new_tagname})" puts '' ticket.assigned_user_id = get_user_id ticket.save rescue NoMethodError puts "(There was an error while assigning this ticket, you man need to run 'bugflow open' and make the necessary changes)" end def gitdir ret = %x{git rev-parse --git-dir}.chomp return Dir.pwd if ret=='.git' return File.dirname ret end end begin Dir.chdir BugFixing.gitdir end begin BugFixing.send(*ARGV) rescue ArgumentError STDERR.puts "Wrong number of arguments." rescue NoMethodError STDERR.puts "Command not recognized." BugFixing.usage end