Integrating Subversion into Basecamp and Campfire

October 5th, 2007 by Joel

For the last few days, I have been thinking about how me and the team around me can improve productivity and communications when developing. Currently, the system we use is a little disjointed, and utilizes several different systems and solutions. Fortunately one such solution is Basecamp, which happens to be one of the best around and has been in use by the company for a while now. So after spending a little time with the web based application, I realised that it should be able to do, or at least manage everything we do.

So last night I sat down and played with the Basecamp API, to see what could be done with it. And I came up with a post-commit hook for Subversion, that posts a message for each subversion commit. This message tells me the change log, what files were changed, and who made the commit. So now we can all see and receive Basecamp notices for every single changeset.

We have also started using Campfire, so I then had a little play with Tinder; Campfire’s unofficial API, and added some more code to the Subversion hook. So as well as creating a message in Basecamp detailing each Changeset, the same changeset is also posted in the appropriate Campfire room. So we have a real time view of our development progress.

So here is the code. It’s all in Ruby, as it was easy peasy. And it utilises the Basecamp API Wrapper.

  1. %w( rubygems tinder basecamp ).each { |f| require f }
  2.  
  3. config = {
  4. :subdomain => 'My-Subdomain', # Campfire and Basecamp subdomain
  5. :email => 'user@mydomain.com', # Campfire email login
  6. :username => 'username', # Basecamp username
  7. :pass => 'password',
  8. :room => 'Development', # Campfire room
  9. :project_id => 12345, # Basecamp project id
  10. :category_id => 678910, # Basecamp message category ID
  11. :ssl => true
  12. }
  13.  
  14. svnlook = '/usr/bin/svnlook' # full path to the svnlook command
  15. repo_path = ARGV[0]
  16. revision = ARGV[1]
  17. project = repo_path.split('/').last
  18.  
  19. commit_author = `#{svnlook} author #{repo_path} -r #{revision}`.chop
  20. commit_log = `#{svnlook} log #{repo_path} -r #{revision}`
  21. commit_files = `#{svnlook} changed #{repo_path} -r #{revision}`
  22.  
  23. # create a message in basecamp
  24. basecamp = Basecamp.new("#{config[:subdomain]}.projectpath.com", config[:username], config[:pass], true)
  25. basecamp.post_message config[:project_id], {
  26. :title => "Changeset ##{revision}",
  27. :body => "#{commit_author} just committed changeset ##{revision}…\n\n<blockquote><pre>#{commit_log}\n#{commit_files}</pre></blockquote>",
  28. :category_id => config[:category_id]
  29. }
  30.  
  31. # create a message in campfire
  32. campfire = Tinder::Campfire.new(config[:subdomain], :ssl => config[:ssl])
  33. campfire.login config[:email], config[:pass]
  34. room = campfire.find_room_by_name config[:room]
  35. room.speak "#{commit_author} just committed changeset ##{revision}…"
  36. room.paste "#{commit_log}\n#{commit_files}"
  37. </code>

Simply copy and paste this into a file called ‘post-commit.rb’ and save that in your subversion repository’s hooks directory. Don’t forget to set its permissions as required (chmod 755 on linux/unix). Then create another file in your hooks directory and call it ‘post-commit’ and do the same with the permissions. In the ‘post-commit’ file, paste the following code:

#!/bin/sh
  1.  
  2. REPOS="$1"
  3. REV="$2"
  4.  
  5. ruby /Users/joelmoss/dev/src/testing/hooks/campfire.rb "$REPOS" "$REV"
  6. </code>

If ‘post-commit’ already exists, just append the last line above to the end of the file.

You will then need to install a few Ruby Gems. Namely Tinder and XML-Simple. So just run the following command:

sudo gem install tinder xml-simple --include-dependencies

And finally, you will need the Basecamp API wrapper. You can get that at http://www.basecamphq.com/api/basecamp.rb. Save that in somewhere in your Ruby path. Ideally, that would be in your ’siteruby’ directly. On my Mac, that is at ‘/usr/local/lib/ruby/siteruby/1.8/’.

And now you should be good to go. As long as you have enabled the API in your Basecamp and your settings are correct, whenever anyone makes a commit to Subversion, you will all be able to see it in Basecamp and Campfire.

I plan to do more with this, as we will need a better bug management system, as Bugzilla is just so damn ugly. But I will leave that to another post.

Enjoy!

Is CakePHP, Ruby on Rails’ biggest fan?

August 26th, 2007 by Joel

Just watched Ruby on Rails Commercial #6 from the guys at RailsEnvy today, and I gotta admit, it really does come very close to the truth.

A lot of the features in CakePHP have been influenced by those features already found in Rails, r simply copied from Rails. Of course I am not part of the Cake core team, so I don’t know how or why such features were included. But you know what? Does it really matter? DHH and Rails should really be very flattered. Why reinvent the wheel, when someone has already done it for you?

What do you think?

My journey on Rails

January 6th, 2007 by Joel

Well this week, after months of “will I won’t I?”, and “shall I, should I?”, I finally sat down and began to write my first app with Ruby on Rails. And you know what? It was, and is fun!

Admitedly, I haven’t gotten very far, but I do now have a basic understanding of the Ruby language and how Rails works. And I can’t yet say whether I will be saying bye to Cake and PHP. I still want to do more with Rails and really see if I can develop faster and easier.

But what I would like to do right now, is give those of you who were in the same boat as me, who want to learn Rails but don’t know where to start. The following are a list of resources that I have found invaluable in my learning of Ruby and Rails.

Walk before you can run

Some of you may not know this, but Ruby on Rails is not a programming language, it is a framework, or collection of scripts written in the Ruby programming language, that provide faster and enjoyable development. I could tell you to launch straight into Rails, but that would be foolish, as you gotta learn to walk before you can run.

The best start I can possibly recommend is to run through the “Try Ruby in 15 minutes” interactive tutorial. Just sit back and watch and learn.

Try a Humble Little Ruby Book

Although I first started to read Ruby for Rails, I didn’t really fully grasp the Ruby language until I read Mr. Neighborly’s Humble Little Ruby Book.

Readable online and in PDF, this free six chapter ebook is written so well and explains the basics of Ruby.

An up to date book on Ruby programming, written in a style described as “a beautiful display of pragmatically chunky bacon, wrapped in a nutshell.” Or something like that.

Mr. Neighborly’s Humble Little Ruby Book covers the Ruby language from the very basics of using puts to put naughty phrases on the screen all the way to serving up your favorite web page from WEBrick or connecting to your favorite web service. Written in a conversational narrative rather than like a dry reference book, Mr. Neighborly’s Humble Little Ruby Book is an easy to read, easy to follow guide to all things Ruby.

Get Agile with Rails

By now you should have a basic understanding of Ruby and are probably chewing at the bit to get started with Rails. So read the last book you will every need - Agile Web Development with Rails.

This award winning book really explains Rails in a way that will get you started immediately.

With this book, you’ll learn how to use ActiveRecord to connect business objects and database tables. No more painful object-relational mapping. Just create your business objects and let Rails do the rest. Need to create and modify your schema? Migrations make it painless (and they’re versioned, so you can roll changes backward and forward). You’ll learn how to use the Action Pack framework to route incoming requests and render pages using easy-to-write templates and components. See how to exploit the Rails service frameworks to send emails, implement web services, and create dynamic, user-centric web-pages using built-in Javascript and Ajax support. There are extensive chapters on testing, deployment, and scaling.

The Official docs

The Ruby and Rails community is thriving, and so there are plenty of well written blogs out there that are perfect companion pieces for your journey on Rails. But before I tell you about the best ones, don’t forget about the official Ruby on Rails site.

The API should always be left open in your browser for quick reference. And although in desperate need of gardening, the Rails Wiki is also a great place to find community generated tips, howto’s and tutorials.

Other Valuable Resources

So what else is there? Just take a look at these worthy reads:

Ruby and Rails Blogs

Often the best blogs are written by the members of the Rail core team, but I also found some others:

Go Forth and roll

Well I think that just about covers everything I used during my week of rolling with Rails. I hope you will find it helpful. Enjoy and let me know if you have found any great RoR resources.

Ruby for PHPers

December 9th, 2006 by Joel

Just found a great little article that introduces Ruby to PHP programmers.

While Ruby’s documentation is at a point now where beginners can start digging in and learning quite rapidly, there appears to be a learning curve with developers coming from other languages. Ruby is a language that took the best ideas from many languages such as Perl, Lisp, Smalltalk, and others, and while some syntax is immediately familiar to a PHP developer, the more you really unlock the power of the language, the less it looks like anything we’ve seen before.

It’s definately worth a read.

HAML into PHAML?

December 3rd, 2006 by Joel

I discovered HAML several months ago and instantly fell in love with it. I can just see how it would increase any developers productivity and speed up development time. Not to mention actually producing nice, clean and great looking XHTML markup.

This is your template:

!!!
%html{ :xmlns => "http://www.w3.org/1999/xhtml", :lang => "en", 'xml:lang' => "en" }
%head
%title BoBlog
%meta{ 'http-equiv' => 'Content-Type', :content => 'text/html; charset=utf-8' }/
= stylesheet_link_tag 'main'
%body
#header
%h1 BoBlog
%h2 Bob's Blog
#content
- @entries.each do |entry|
.entry
%h3.title= entry.title
%p.date= entry.posted.strftime("%A, %B %d, %Y")
%p.body= entry.body
#footer
%p
All content copyright