<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kabisa Blog &#187; Ludo van den Boom</title>
	<atom:link href="http://blog.kabisa.nl/author/ludo/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.kabisa.nl</link>
	<description>The Ruby on Rails Experts</description>
	<lastBuildDate>Sun, 09 Oct 2011 07:54:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Headless Cucumbers and Capybaras with Selenium and Hudson</title>
		<link>http://blog.kabisa.nl/2010/05/24/headless-cucumbers-and-capybaras-with-selenium-and-hudson/</link>
		<comments>http://blog.kabisa.nl/2010/05/24/headless-cucumbers-and-capybaras-with-selenium-and-hudson/#comments</comments>
		<pubDate>Mon, 24 May 2010 18:01:14 +0000</pubDate>
		<dc:creator>Ludo van den Boom</dc:creator>
				<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[capybara]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[hudson]]></category>

		<guid isPermaLink="false">http://blog.kabisa.nl/?p=94</guid>
		<description><![CDATA[Nowadays software engineers can&#8217;t live without their favorite test frameworks. But what a software engineer does not want is having to put a lot of effort in keeping these test run. Neither do teams of software engineers want to spent much time on making their test results visible to the entire team. More and more [...]]]></description>
			<content:encoded><![CDATA[<p>Nowadays software engineers can&#8217;t live without their favorite test frameworks. But what a software engineer does not want is having to put a lot of effort in keeping these test run. Neither do teams of software engineers want to spent much time on making their test results visible to the entire team.</p>
<p>More and more useful applications, libraries and plugins are appearing that take away some of the pain that is sometimes involved in making software tests useful for entire teams. Examples of excellent tools that we have at our disposal right now are <a href="http://hudson-ci.org/">Hudson</a> for continuous integration, <a href="http://cukes.info">Cucumber</a> for integration tests and <a href="http://seleniumhq.org/">Selenium</a> for automated testing of web applications in an actual browser. But making all these play together nicely involves more and more setting up of build servers and configuration.</p>
<p>Our goal is to document the steps required to overcome one of the hurdles that we kept running into, namely running our full Cucumber test suite including all Selenium scenarios on our Hudson integration server.</p>
<h2>Ingredients</h2>
<p>We&#8217;re going to use the following ingredients in this post:</p>
<ul>
<li>1 Debian 5.0.4 &#8216;Lenny&#8217; installation</li>
<li>1 installation of <a href="http://en.wikipedia.org/wiki/Xvfb">Xvfb</a></li>
<li>1 web browser (in our case <a href="http://www.geticeweasel.org/">iceweasel</a>, Firefox rebranded by Debian)</li>
<li>1 Ruby on Rails 2.3.7 application</li>
<li>1 Capybara 0.3.8 gem</li>
<li>As many Cucumbers (0.7.3) as necessary</li>
</ul>
<p>We won&#8217;t go into the details of creating a Rails application, installing the gems and writing the Cucumber scenarios here. Their manuals are perfect guides for this.</p>
<h2>Installing required packages</h2>
<p>We start with installing a couple of packages that allow us to run headless tests in a web browser.</p>
<h3>Virtual framebuffer with Xvfb</h3>
<blockquote><p><em>&#8220;In the X Window System, Xvfb or X virtual framebuffer is an X11 server that performs all graphical operations in memory, not showing any screen output.&#8221;</em> <small>Source: <a href="http://en.wikipedia.org/wiki/Xvfb">http://en.wikipedia.org/wiki/Xvfb</a></small></p></blockquote>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> xvfb</pre></div></div>

<h3>Web browser</h3>
<p>After installing Xvfb we can go ahead and install a web browser.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> iceweasel</pre></div></div>

<p>Before we continue we want to configure our browser profile so that it doesn&#8217;t whine about tabs being closed or not resuming correctly after it has crashed. If we don&#8217;t do this, our test suite might crash or run forever.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">cd</span> ~<span style="color: #000000; font-weight: bold;">/</span>.mozilla<span style="color: #000000; font-weight: bold;">/</span>firefox<span style="color: #000000; font-weight: bold;">/</span>xxxxxxxx.default<span style="color: #000000; font-weight: bold;">/</span>
$ <span style="color: #c20cb9; font-weight: bold;">vim</span> user.js</pre></div></div>

<p>Now put the following two lines in the user.js file:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">user_pref(&quot;browser.sessionstore.enabled&quot;, false);
user_pref(&quot;browser.sessionstore.resume_from_crash&quot;, false);</pre></div></div>

<h3>Test Display</h3>
<p>Before we start running our tests we will ant to verify that all packages were installed successfully. To do so start a virtual framebuffer (an Xvfb session) on display 99 with screen 0:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ Xvfb :<span style="color: #000000;">99</span> <span style="color: #660033;">-ac</span> <span style="color: #660033;">-screen</span> <span style="color: #000000;">0</span> 1024x768x16</pre></div></div>

<p>In a different terminal window do:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #007800;">DISPLAY</span>=:<span style="color: #000000;">99.0</span> iceweasel http:<span style="color: #000000; font-weight: bold;">//</span>example.org</pre></div></div>

<p>This will start our web browser in the virtual framebuffer and open the example.com homepage in this browser. Next up is makinga &#8216;screenshot&#8217; so that we can see what is going on inside our virtual framebuffer.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ xwd <span style="color: #660033;">-root</span> <span style="color: #660033;">-display</span> :<span style="color: #000000;">99.0</span> <span style="color: #660033;">-out</span> xwdout</pre></div></div>

<p>And subsequently view the screenshot using:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ xwud <span style="color: #660033;">-in</span> xwdout</pre></div></div>

<p>Do you see the example.org homepage? Then Xvfb and iceweasel were installed successfully and we are now ready to do some testing.</p>
<div id="attachment_125" class="wp-caption aligncenter" style="width: 538px"><a href="http://blog.kabisa.nl/wp-content/uploads/2010/05/xwud.jpg"><img class="size-full wp-image-125" title="Iceweasel in Xvfb" src="http://blog.kabisa.nl/wp-content/uploads/2010/05/xwud.jpg" alt="Iceweasel in Xvfb" width="528" height="411" /></a><p class="wp-caption-text">Iceweasel in Xvfb</p></div>
<h2>Running cucumbers</h2>
<p>Before we integrate this setup into our continuous integration environment we do a test run to see if the cucumbers work with our new configuration. We can do this using the following command, keep in mind that we have to explicitly tell the cucumbers to use our virtual framebuffer display:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #007800;">DISPLAY</span>=:<span style="color: #000000;">99.0</span> rake cucumber</pre></div></div>

<p>If all goes well then we will see that all scenarios passed. If not all scenarios pass first check if they do run on in a non-headless situation.</p>
<h2>Configuring Hudson</h2>
<p>Now we have come to the point where we can tie all strings together. We need to add a new build step to the job that needs to run headless cucumbers. But, before adding this build step, we will create a start/stop script for our virtual framebuffer. This script can be used to start a buffer before running the scenarios, and stop the buffer after the scenarios completed. You can save this script to /etc/init.d. Make sure that the permissions are set so that the user that runs Hudson can execute it.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">XVFB</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>Xvfb
<span style="color: #007800;">XVFBARGS</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$DISPLAY</span> -ac -screen 0 1024x768x16&quot;</span>
<span style="color: #007800;">PIDFILE</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>hudson<span style="color: #000000; font-weight: bold;">/</span>xvfb_<span style="color: #800000;">${DISPLAY:1}</span>.pid
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
  start<span style="color: #7a0874; font-weight: bold;">&#41;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Starting virtual X frame buffer: Xvfb&quot;</span>
    <span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>start-stop-daemon <span style="color: #660033;">--start</span> <span style="color: #660033;">--quiet</span> <span style="color: #660033;">--pidfile</span> <span style="color: #007800;">$PIDFILE</span> <span style="color: #660033;">--make-pidfile</span> <span style="color: #660033;">--background</span> <span style="color: #660033;">--exec</span> <span style="color: #007800;">$XVFB</span> <span style="color: #660033;">--</span> <span style="color: #007800;">$XVFBARGS</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;.&quot;</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
  stop<span style="color: #7a0874; font-weight: bold;">&#41;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Stopping virtual X frame buffer: Xvfb&quot;</span>
    <span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>start-stop-daemon <span style="color: #660033;">--stop</span> <span style="color: #660033;">--quiet</span> <span style="color: #660033;">--pidfile</span> <span style="color: #007800;">$PIDFILE</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;.&quot;</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
  restart<span style="color: #7a0874; font-weight: bold;">&#41;</span>
    <span style="color: #007800;">$0</span> stop
    <span style="color: #007800;">$0</span> start
    <span style="color: #000000; font-weight: bold;">;;</span>
  <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
  <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Usage: /etc/init.d/xvfb {start|stop|restart}&quot;</span>
  <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">esac</span>
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span></pre></div></div>

<p><small>Source: <a href="http://marc.info/?l=tomcat-user&#038;m=102335321103262&#038;w=2">http://marc.info/?l=tomcat-user&#038;m=102335321103262&#038;w=2</a></small></p>
<p>Final step is to add an &#8216;Execute shell&#8217; build script to our Hudson job. You can use the following set of commands to run your cucumbers.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">DISPLAY</span>=:<span style="color: #000000;">99</span>
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>xvfb start
rake cucumber
<span style="color: #007800;">RESULT</span>=<span style="color: #007800;">$?</span>
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>xvfb stop
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #007800;">$RESULT</span></pre></div></div>

<p>After adding this build step we save our job and let Hudson build it. If all goes well the cucumber scenarios should now be running as part of our continuous integration process. You can check the &#8216;Console output&#8217; page of a Build in Hudson for hints when it didn&#8217;t run successfully.</p>
<h2>Conclusion</h2>
<p>If you have followed along with this post then you should have a working, headless setup by now. The advantage of this setup is that it is pretty light-weight and easy to setup. But this setup is not suited for you if you need to test across multiple browsers on different browsers. For such a setup you will want to have a look at virtual machines and Hudson slave agents.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kabisa.nl/2010/05/24/headless-cucumbers-and-capybaras-with-selenium-and-hudson/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Using transactions with Ruby DataMapper</title>
		<link>http://blog.kabisa.nl/2010/01/21/using-transactions-with-ruby-datamapper/</link>
		<comments>http://blog.kabisa.nl/2010/01/21/using-transactions-with-ruby-datamapper/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 19:25:38 +0000</pubDate>
		<dc:creator>Ludo van den Boom</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.kabisa.nl/?p=52</guid>
		<description><![CDATA[With DataMapper, it can be quite a challenge to perform tasks that seem so simple at first. DataMapper is an object-relational mapper (ORM) written in Ruby, with a lot of great features and innovative approaches to common ORM-tasks. But it lacks documentation for some of the less-used features and even the more popular search engines [...]]]></description>
			<content:encoded><![CDATA[<p>With <a href="http://datamapper.org">DataMapper</a>, it can be quite a challenge to perform tasks that seem so simple at first. DataMapper is an object-relational mapper (ORM) written in Ruby, with a lot of great features and innovative approaches to common ORM-tasks. But it lacks documentation for some of the less-used features and even the more popular search engines don&#8217;t have the answer to all questions.</p>
<p>Note: the following examples have been tested with DataMapper version 0.10.2.</p>
<p>One of the questions I had was how to perform multiple queries within a single (database) transaction, so that I can &#8216;stage&#8217; a number of database queries and commit (or rollback) them all in one go. Fortunately, after some investigation of the DataMapper source code, it turns out to be an extremely simple task:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">User.<span style="color:#9900CC;">transaction</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  User.<span style="color:#9900CC;">first</span>.<span style="color:#9900CC;">update</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;John Smith&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  Address.<span style="color:#9900CC;">first</span>.<span style="color:#9900CC;">update</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:street</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># Invalid: street must not be blank</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>With this code neither the address nor the user will be updated in the database if one of the updates fails. The syntax is actually the same as for the <a href="http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html">ActiveRecord</a> ORM. However, triggering a rollback is done differently, as can be seen in the following example.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">User.<span style="color:#9900CC;">transaction</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
  User.<span style="color:#9900CC;">first</span>.<span style="color:#9900CC;">update</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;John Smith&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  Address.<span style="color:#9900CC;">first</span>.<span style="color:#9900CC;">update</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:street</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;Oak St. 400&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  t.<span style="color:#9900CC;">rollback</span> <span style="color:#008000; font-style:italic;"># Transaction will be rolled back even when updates are OK.</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>That&#8217;s it for now. I&#8217;m sure there are some additional features that I haven&#8217;t mentioned here, but this is all I had to know at this point.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kabisa.nl/2010/01/21/using-transactions-with-ruby-datamapper/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Giving Love To the Community</title>
		<link>http://blog.kabisa.nl/2009/11/27/giving-love-to-the-community/</link>
		<comments>http://blog.kabisa.nl/2009/11/27/giving-love-to-the-community/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 11:09:27 +0000</pubDate>
		<dc:creator>Ludo van den Boom</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[railsconf]]></category>
		<category><![CDATA[rumble]]></category>

		<guid isPermaLink="false">http://blog.kabisa.nl/?p=3</guid>
		<description><![CDATA[Earlier this month Kabisa attended the Ruby en Rails 2009 conference in Amsterdam. Ruby en Rails is the largest dedicated Ruby and Rails conference in the Netherlands. For the first time in its history Ruby en Rails was a multiple day event. The first day, October 31, was packed with interesting presentations on various Ruby [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this month Kabisa attended the <a title="Ruby en Rails 2009 Homepage" href="http://2009.rubyenrails.nl">Ruby en Rails 2009</a> conference in Amsterdam. Ruby en Rails is the largest dedicated Ruby and Rails conference in the Netherlands.</p>
<p>For the first time in its history Ruby en Rails was a multiple day event. The first day, October 31, was packed with interesting presentations on various Ruby and Rails related topics, by great speakers including renowned community idols like Yehuda Katz, Jeremy Kemper, Jonathan Weiss and many more. The second day (the &#8216;geek-day&#8217;) focused on more practical sessions and lightning talks. On this day another event was held: The RubyEnRails Rumble (RERR), a competition where teams of two had to complete an assignment within a certain time.<br />
<span id="more-3"></span><br />
Since we from Kabisa consider ourselves to be Ruby programmers we wanted to take the challenge and see how we would do in this competition. Michel de Graaf and Ludo van den Boom were given the honor to rumble for Kabisa. This post will describe how we prepared for the RubyEnRails Rumble and how we have experienced it.</p>
<h2>Rumble Preparations</h2>
<p>After deciding that we would partake in the Rumble we knew that we would have to prepare ourselves as good as possible so that we could utilize our time at the Rumble as efficiently as possible. Neither of us had ever participated in an event like this, so we started of with a session in which we tried to decide what we could do to help us prepare for the Rumble. Together with our Kabisa colleagues we made a list of items and topics that could prove to be handy during the Rumble.</p>
<p>The hard part was that we had no experience and that we did not know what the assignment would be, so we dove into a broad range of subjects. With help from our colleagues we were able to refresh our knowledge of Ruby and Rails related technologies and built up a collection of snippets/links to quickly be able to perform standard tasks like retrieving tweets from Twitter and adding jQuery UI sugar to an application. In the end we prepared a <a href="http://github.com/ludo/rerr_template">Rails application template</a> so that we would be able to quickly set-up a Rails skeleton application including basic functionality like authentication and authorization. Besides this template we also prepared a user interface template builder that could help us to quickly apply a &#8216;theme/skin&#8217; to an application (<a href="http://github.com/michel/interfaceLift">interfaceLift</a>).</p>
<p>For scaffolding we used <a href="http://github.com/grimen/dry_scaffold">dry_scaffold</a>: This gem contains a rails generator that will replace the default rails scaffolding with more up to date DRY controllers and views. Controllers are implemented using <a href="http://github.com/josevalim/inherited_resources/tree/master">inherited_resources</a>. And the views are generated in <a href="http://haml-lang.com/">haml</a> that make use of <a href="http://github.com/justinfrench/formtastic">Formtastic Forms</a> to generate nice looking forms. The <a href="http://github.com/michel/dry_scaffold">fork</a> we where using also generated a search form that was implemented using <a href="http://github.com/binarylogic/searchlogic">searchlogic</a>.</p>
<p>Another challenge was that we had not worked together before. So, apart from the technical toolkit that we set-up, we also had to find a way to get more acquainted with each others good and bad sides. We decided that the best way to do this would be to simulate a Rumble, and that&#8217;s what we did. Our colleague Ralph came up with an assignment that we worked on for about six hours. In these six hours we managed to crank out some decent results and learned how we could best divide the development tasks to our individual skill sets. This simulation prepared us for lots of things but it did not really simulate the most vital element of a competition: stress.</p>
<h2>Rumble Ramblings</h2>
<p>Some hints on what the assignment would be were dropped during the presentations on the first day. Still, we could only guess what exactly to expect. At the start of the Rumble the assignment was introduced and explained, the assignment was titled &#8216;Community Love&#8217;. It turned out that we had to create a system that would keep users of Ruby libraries up-to-date with updates about these libraries. The assignment was kept vague on purpose so that the teams had the ability to put their creative minds to work with finding a solution to the problems laid out in the assignment description.</p>
<p>So, now we had a little under eight hours left to design and build something that would convince the jury of our programming skills. After a short stand-up meeting we came up with a rough idea for what we would create.</p>
<h3>The Plan&#8230;</h3>
<p>As a Ruby/Rails developer you will probably make use of lots of gems in your application. You can specify these gem dependencies in your Rails configuration. Or make use of the awesome gem <a href="http://github.com/wycats/bundler">bundler</a>. This will help you manage gem dependencies but they will not inform you when there are updates to the gems you are using. We figured that, as a developer who uses gems in a Ruby project you should be able to send a list of gem dependencies you use in a specific application to a service that will inform you when there are updates to the gems that you are using. An update could, for example, be a new version, a reported security vulnerability or a blog post. Since we had only one day to build something, we decided to focus on Rubygems exclusively. Mostly because there are already good centralized repositories where we would be able to easily find information about gems (gemcutter).</p>
<h3>&#8230; And the Solution &#8230;</h3>
<p>Our solution consists of three parts: (1) a gem that you use locally to update the list of gems you use in particular applications, (2) an online service (Rails application) where you can see the gems you use and (3) notification channels (i.e. email and twitter) through which news about gems is pushed to you. We named our solution &#8216;gemstreamer&#8217;, for it would stream information about gems to you as a user of these gems. For those of you who are interested to see what we actually made: you can see the &#8216;online service&#8217; Rails application that is used as the central &#8216;information hub&#8217; where information is gathered and distributed at <a href="http://github.com/ludo/rerr2009">http://github.com/ludo/rerr2009</a>. For the gem that you would use locally to push the gems you use to the central hub see <a href="http://github.com/michel/gemstreamer">http://github.com/michel/gemstreamer</a>. We deliberately kept the code as simple as possible and leveraged as many existing tools as possible to be able to quickly get things done. The end result is pretty simple, but the ideas behind it might actually be useful when extended and polished for real-life usage. This was also one of the comments from the jury, where they believed that something like this could make a great extension to <a href="http://gemcutter.org">http://gemcutter.org</a>.</p>
<h3>&#8230; At a Price</h3>
<p>Did we mention the stress? Apparently we were both not very satisfied with how we made progress. There was so much that we wanted to do, and so little time to do it all. This is probably the biggest flaw in how we approached the Rumble. Before the Rumble we had already discussed that it would be best to make something small that works instead of something big that does not work. This reasoning sounded really good before the Rumble and after the Rumble, but we actually forgot it during the Rumble&#8230; Still, we managed to get our main ideas implemented which we were able to present at the end of the day.</p>
<h2>Rumble Opponents</h2>
<p>With five pretty strong teams the competition was fierce. It was interesting to see that every team approached the assignment from a different angle. Where our end result can be seen as an interesting prototype, others had created something that could be of use to developers right away. Here is a short summary of what the other teams created:</p>
<ul>
<li>The Fingertips team created <a href="http://www.fngtps.com/2009/11/apprise">Apprise</a> for which they patched <a href="http://github.com/wycats/bundler">Bundler</a>. This patch to was applied to Bundler By Yehuda the very next day.</li>
<li>Iain Hecker and Marcel de Graaf built an extension to Webistrano that shows outdated gems, named &#8216;<a href="http://github.com/Thyraon/rer09">deproll</a>&#8216;.</li>
<li>The i76 team (Tom-Eric Gerritsen and Rik Tonnard) built a Rails plugin that you can hook-up in your application so that you can see the dependencies that your app uses through a web interface (<a href="http://github.com/i76/rrrer2009">http://github.com/i76/rrrer2009</a>).</li>
<li>Leon Berenschot and Klaas-Jan Wierenga gave a cool presentation and won the Twitter vote (<a href="http://github.com/LeipeLeon/Dev-Enter">http://github.com/LeipeLeon/Dev-Enter</a>).</li>
</ul>
<h2>Rumble Results</h2>
<p>Victory! Completely unexpected we were awarded the first prize: two tickets to <a title="RailsConf 2010 Homepage" href="http://en.oreilly.com/rails2010">RailsConf 2010</a> in Baltimore, MD. The winner was selected by a jury and through public voting via Twitter. In the Twitter vote we ended as third, which we thought was already a great achievement. But the professional jury had unanimously picked us! These two votes combined made us the overall winners of the Ruby en Rails Rumble 2009: awesome!</p>
<p>In hindsight we can conclude that our plan was a little too ambitious as it turned out that eight hours is really not that much. Nonetheless, the rumble turned out to be a great experience that was really fun doing. It was a crazy day with a lot of stress, but it was also an interesting experiment to see how we would do against some other very good teams. The end result turned out to be even better than what we&#8217;ve hoped for. We want to thank the jury for choosing us as well as the people who voted for us on Twitter. Last but not least many thanks to the people who made Ruby en Rails possible this year, we had a great time!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kabisa.nl/2009/11/27/giving-love-to-the-community/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

