re-imagining coding IDE's

Because everything currently sux.
Check out this amazing and inspiring video:

Tks to Victor Oliveira for showing me this.

Some thoughts on continuous integration and branching management with git

Some weeks ago I came across the subject of development workflow while working at my previous company and I wasn't really satisfied with what we had. Also I felt there was something missing and was unhappy with my own ideas of what the perfect workflow would be. So I did some research to see what people out there is doing and to form a better opinion.

It seems there are two major workflows on can follow: continuous integration and feature branching.

Continuous Integration

The basic idea with CI is to commit often and integrate with the main line often (daily at least), so to avoid conflicts.
What I like about it is that you actually resolve conflicts early (everybody hates conflicts, right?).
What I dislike is the fact that you might be pushing unfinished or unpolished code and it seems to require more planning from the developer about what he's pushing to the main line.

Feature Branching

With feature branching we create separate branches for different features and work on those branches until the feature is done.
What I like about it is that you can keep your code and commits tider and you separate unfinished code from the main branch.
What I dislike is the fact that the longer you take to integrate with the main branch the more conflicts you might have.


So can't we have the best of the both worlds?

A guy called Adam Dymitruk described what for me was always the main issue with iteration based development: Taking features out is more powerful than putting them in.
So you are doing CI, you've put your features in but at the last moment you realized one feature is buggy or not complete and you want to take it out. What do you do? There you go reverting commits (in the simplest case).

After reading all these stuff I came with a list of requirements of what the perfect workflow would give me:

  1. I want to be able to keep the commit history tidy. I want to be able to sort my commits, amend it, peer review it and edit it as much as necessary so it because tidy, logical and beautiful before getting into main stream branch. I want to avoid commits that fixes commits. A commit history of a feature should appear like it was perfect from the first time instead of a succession of trial and errors.
  2. I want to be able to generate a release build with selected features at any time I want, leaving the features that I don't want out.
  3. I want to anticipate integration errors and conflicts so they are fixed early. 

Is there a way we can satisfy all these requirements?

A missing tool

I really believe there's a missing tool here. Adam Dymitruk seems to have written a script to share git conflict resolutions using git rerere. But apparently he hasn't shared it yet.
What I think this tool should do is the following:

Given a stable/production branch P, and a set of feature branches, say, FB1, FB2 and FB3, I want a system that:
  • Combines (merge) P with every branch and test it, say P + FB1, P + FB2, P + FB3.
  • Select the successful branches and try to merge them together. Say FB2 failed, so we would try to build and test P + FB1 + FB3 and make it a release candidate.
  • Should a conflict appear, notify the developers so they can fix it.
  • The conflict resolution is saved so not to happen again.
  • The process is repeated continuously.

I think there could be a tool on top of git to do such process and it seems to have many issues involved. 
I'm really looking forward to see such a tool (and might end up doing something myself).
I wonder if this would approach actually work in practice...

A couple of links from google I/O 2011

A little toy todo list using ruby on rails

A potential employer asked me to build a toy todo list using ruby on rails to test my skills with a few things. I spent some time yesterday doing it and here is the result: Yats4p.

 A short list of what I've used:

There's a live version running on heroku.
And yes, there are some bugs and polishing to be done yet ;-)
Critiques and comments are more than welcome.

Semantic rspec view matchers with rspec-html-matcher gem

Lately I've been concerned about writing specs for rails views and I came across the rspec-html-matchers gem.

I won't repeat the documentation here but the idea is quite simple.
Render your view using rspec and then match it using something sweet like:

rendered.should have_tag(:form) do
  with_tag :input, :with => { :name => "foo"}

It's much quicker and efficient than parsing the html yourself using nokogiri for example.

Vim, RVM, VirtualBox and SSH: my current ruby on rails development environment

As a former Linux + C developer, I've spent most of my early days with a very simple (yet powerful) set of tool: a terminal, vim and make.
My development cycle was quite simple:

Make your changes:
$> vim file.c

Compile it
$> make

Run and test your program by hand
$> ./my-program

Debug it
$> gdb ./my-program

That was all I needed for many years.

And so came along the magic of ruby and rails and things started getting a little bit more complex than that. Also I moved away from Linux as a desktop environment and started using OSX, which just added more chaos to the development setup.
Truth is, although OSX is unix based, posix, etc, etc and you CAN run the same stuff as you do on Linux, things are always simpler with linux in terms of open source development.
You have better support, better packaging, etc.

I've tried and used for a while my whole rails stack straight into my OSX box. But after some time you have to upgrade things, install dependencies, then you get trouble with ports, brew, whatever you are using, your environment starts getting a mess and you wish you were using Make and C again in 2001.

I've tried TextMate for while. It's kind of nice, but I really missed Vim.

So, enough history, here's how I develop for rails currently:

Isolate everything using VirtualBox

First I isolate everything inside a virtual machine under VirtualBox. VirtualBox is free and very simple to use.
It also can create snapshots of your vm (which I recommend), so you can rollback your environment if things get screwed (it does sometimes).

It's much quicker to just rollback a vm than reinstall the whole stack again.
For the brave and advanced user, you can even automate the bootstrap of you vm using Vagrant.
It's nice if you several dependencies and you want to share it with a team.

As OS preference I use Ubuntu. I have never tried anything else other than slackware in the past, but I've been quite happy with it so I don't see a point in changing.

So what I do is create a virtual box, get the latest ubuntu server and install into it.

Connect to your environment

You have basically two options with your vm: either you use it as a full graphical system or you connect to it using SSH. I prefer the latter because I don't lose my actual desktop interface (OSX).
For using the VM over SSH, I recommend setting the Network settings to use NAT and configure proper port forwarding (more on it below).

I usually setup:

  • localhost 2280 to port 22 on the vm, and
  • localhost 3080 to port 3000 on the vm.

I don't like bridge network because you can have your vm's ip changing over time which just make things worse.

So just open a terminal and connect to localhost on port 2280 (which will forward to port 22 in the vm).
If you are using something like OSX, I recommend you also create aliases for ssh to speed things up.

I usually put into my ˜/.ssh/config file:

host dev
user myusername
hostname localhost
port 2280

With this I can more easily type:
  $> ssh dev
Instead of
  $> ssh myusername@localhost -p 8022

Using X from inside SSH

Surprisingly, you can run X applications from inside your SSH connection using something called X11 forwarding.

Doing this is very simple, given you have X on your host (which you do if you are running OSX).
Simply connect to you box passing -X to ssh:
  $> ssh dev -X

The -X option tells ssh to open a tunnel and forward X11 messages to your host.
After doing that you are able to run you favorite X application from inside your VM straight into your desktop.

For example, after connection to the vm, type:
  $> gvim

This will bring gvim in your desktop. Sweet, isn't it?

Editing your files: GVim, not Vim

As you might have realized from the previous section, I actually use gvim when connected to SSH instead of VIM. Gvim has some advantages over Vim, like better mouse integration, for example (not that you are gonna want to use the mouse...).

Vim is highly customizable and there are some plugins you can use to make your life easier (I highly recommend installing then and taking the time to learn how to use it).
Take a look at the plugins from this guy: Tim Pope

So I like to use these:
  • pathogen: install it first. allows better management of vim plugins
  • most other tpope plugins, take a look and pick the ones you like
  • NerdTree: adds a file browser like capability to vim
  • Comman-t: TextMate like command-t to search for filenames.
I'm not going to teach how to use vim here. You can always type "how do I..." on google :)

Managing ruby with RVM

When using ruby, you probably want a specific version, or the latest version, or the production's box version, etc. Whatever version it is, it's usually NOT the version your system's packaging system gives you.
So the standard here is to use RVM
Nice thing about it is you can switch between multiple version and run everything inside your local user (not need to mess with your global system files).

Forward you SSH keys to your vm

Another nice trick with SSH is to use agent forwarding. You need an SSH key if you are connecting to a git server, for example, like github. So in general you want to have a single key in your desktop instead of creating an additional key inside the virtual machine.
Worse, you don't really want copy your identity key from your desktop to your VM.
So here is the trick, you can either:
  $> ssh dev -A
or add to your ˜/.ssh/config

ForwardAgent yes

So now you can connect to your VM and use git normally as you would locally. Your keys are forwarded so you don't need to copy it.

Development cycle using TDD, RSPec and Guard

So for the final step, here is where you spend most of your time: writing code.
I came across this gem called Guard. Its principle is quite simple: you keep it running and it monitors your files. As soon as it detects changes it runs your automated tests automatically for you so you have instant feedback of your code.
It supports rspec, cucumber, test:unit, among others and uses a rule system to determine which tests to run for each file that you change. Quite sweet.

So for the most time what I do is have gvim opened where I edit my files and write tests at the same time.
On a separate screen I have guard running where I keep watching the output to get feedback from my code.
This way I can literally use gvim only, without the need to make the "code, compile, test" cycle. It all goes down to a single step: write code, which at the end is what matters.

Final Thoughts

So to summarize, I develop for rails using Vim over SSH. It's quite old school but I find it very powerful.
I'm still optimizing this setup and trying to make it more efficient and the tools work better for me.
Of course I'm open for hints and improvements!

Hope you enjoy :)

speed up your ruby interviews with interview-booster

You are interviewing for a nice ruby job and when you get there someone asks you to solve a simple problem using ruby. No problem, you say.

I always tended to take a lazy approach, open a foo.rb file, stuff the code there and run it over some input text file. STDIN/STDOUT ftw.

In the TDD era it's more interesting if you show you can use TDD straight away and it can also speed up your interview process significantly if you use the guard gem.

That's why I've made Interview Booster. It's nothing more than a repo with a simple skeleton to use guard and Test::Unit.

All you have to do is install the gems, run guard into a terminal and edit your files while guard runs your tests automatically for you as soon as you save a file.

Hey, it's not cheating, it's time saving!
And oh, you can also check this 15 ruby interview questions :)