Every Second Counts with a Piston in your Trunk
Recently, I wrote about using RSpec and autotest (...which I think should be called autospec) together to help boost productivity while working on Rails projects. It seems that a few members of the PLANET ARGON team have picked up on using it, which I’m happy to hear about. :-)
It’s not the only thing that I’m happy about though.
I recently came across another gem. Several of my comrades in #caboose are using piston to manage external plugins for Ruby on Rails. Wait! Isn’t this what Subversion externals is meant for? Well, yes… but externals also eat away at productivity. For example, each day, we may have anywhere from 4-6 designers and developers working on one client project. When we’re in crunch mode, this could account for quite a few subversion commits throughout the day. We all know that we should run svn up
on a regular basis to make sure that we’re keeping things in sync… especially when designers and developers are working really closely and fine tuning something specific in the application. Well, the one downside to this process is that each svn up
not only checks our repository, but it also checks external repositories.
“But wait! Can’t you just ignore externals on an update?”
Of course, but who wants to type out --ignore-externals
each time they run an update? ...or perhaps you could make an alias for this in your shell. In any event, everyone on the team is then left to be responsible for doing this… and an extra 30-60 seconds (if not longer) per svn update times x number of people on project… well… time wasted if you’re closely watching the svn updates. Also, TextMate doesn’t have an option currently (that I could find) to ignore externals, so for those who manage subversion through it… they’re waiting on externals within their primary workspace.
Another issue with svn externals is that when a repository goes down, it really starts to slow stuff down your updates. This is always fun when you go to deploy your application with Capistrano and realize that you can’t finish the update because it can’t connect it to http://svn.lazyatom.com/public/plugins/acts_as_hasselhoff/
to make sure that your application has the latest version of the best plugins available for Rails.
Then there is the whole issue of wanting to make changes to the plugin that you’re including as an external. How does that fit into the whole mix?
There is Hope!
Piston encourages you to keep your external plugins in your local repository. Don’t worry, it remembers where it retrieved the code from so that you can update from the external repository at any time.
Installing Piston
Again, this is really simple like most gems.
$ sudo gem install -y piston
Password:
...
Successfully installed piston-1.2.1
Great, that’s all that you have to do to get started with Piston. Now, let’s get on with the show.
If you don’t have any existing Subversion externals, feel free to skip this section.
Converting existing externals
Okay, so let’s say that you’re working on a Ruby on Rails project and are relying on several external repsitories. For example, a project that I’m working on… currently looks like this.
$ svn proplist --verbose vendor/plugins/
Properties on 'vendor/plugins':
svn:externals :
authorization http://svn.writertopia.com/svn/plugins/authorization
svn_tools http://svn.planetargon.org/rails/plugins/svn_tools
simply_helpful http://dev.rubyonrails.com/svn/rails/plugins/simply_helpful
exception_notification http://dev.rubyonrails.com/svn/rails/plugins/exception_notification
asset_field http://svn.planetargon.org/rails/plugins/asset_field
rspec_on_rails svn://rubyforge.org/var/svn/rspec/tags/REL_0_7_5/rspec_on_rails/vendor/plugins/rspec_on_rails
rspec_autotest http://svn.caldersphere.net/svn/main/plugins/rspec_autotest
Piston is smart enough to know how to convert these Subversion externals into Piston-friendly plugins. This can be done by passing the piston
command the convert option
from within your Rails application directory.
Go ahead and run the following.
$ piston convert
Importing 'http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-0_RC1' to vendor/rails (-r 5619)
Exported r5619 from 'http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-0_RC1' to 'vendor/rails'
Importing 'http://svn.writertopia.com/svn/plugins/authorization' to vendor/plugins/authorization (-r 83)
Exported r83 from 'http://svn.writertopia.com/svn/plugins/authorization' to 'vendor/plugins/authorization'
Importing 'http://svn.planetargon.org/rails/plugins/svn_tools' to vendor/plugins/svn_tools (-r 119)
Exported r119 from 'http://svn.planetargon.org/rails/plugins/svn_tools' to 'vendor/plugins/svn_tools'
Importing 'http://dev.rubyonrails.com/svn/rails/plugins/simply_helpful' to vendor/plugins/simply_helpful (-r 5700)
Exported r5700 from 'http://dev.rubyonrails.com/svn/rails/plugins/simply_helpful' to 'vendor/plugins/simply_helpful'
Importing 'http://dev.rubyonrails.com/svn/rails/plugins/exception_notification' to vendor/plugins/exception_notification (-r 3900)
Exported r3900 from 'http://dev.rubyonrails.com/svn/rails/plugins/exception_notification' to 'vendor/plugins/exception_notification'
Importing 'http://svn.planetargon.org/rails/plugins/asset_field' to vendor/plugins/asset_field (-r 50)
Exported r50 from 'http://svn.planetargon.org/rails/plugins/asset_field' to 'vendor/plugins/asset_field'
Importing 'svn://rubyforge.org/var/svn/rspec/tags/REL_0_7_5/rspec_on_rails/vendor/plugins/rspec_on_rails' to vendor/plugins/rspec_on_rails (-r 1330)
Exported r1330 from 'svn://rubyforge.org/var/svn/rspec/tags/REL_0_7_5/rspec_on_rails/vendor/plugins/rspec_on_rails' to 'vendor/plugins/rspec_on_rails'
Importing 'http://svn.caldersphere.net/svn/main/plugins/rspec_autotest' to vendor/plugins/rspec_autotest (-r 48)
Exported r48 from 'http://svn.caldersphere.net/svn/main/plugins/rspec_autotest' to 'vendor/plugins/rspec_autotest'
Done converting existing svn:externals to Piston
All we have to do now is checkin our changes to subversion and we’re golden.
svn ci -m "updating repository to use piston instead of those lame-o externals..."
If you find this interesting and want to learn more, be sure to check out this post on Ruby Inside for a detailed introduction to Piston.
update
the following morning I saw this come across our development team channel…
< argonbot> svn.commit( project_name, { :author => 'brian.ford', :rev => 83, :log => 'converted svn:externals to piston for product, cus I can.' }
:-)