<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Mate-driven development</title>
 <link href="http://matedriven.com.ar/atom.xml" rel="self"/>
 <link href="http://matedriven.com.ar/"/>
 <updated>2010-03-11T14:18:02-05:00</updated>
 <id>http://matedriven.com.ar/</id>
 <author>
   <name>Matías Flores</name>
   <email>mflores@atlanware.com</email>
 </author>

 
 <entry>
   <title>I Did It My Way - Learning Sinatra by example</title>
   <link href="http://matedriven.com.ar/2010/01/13/i-did-it-my-way.html"/>
   <updated>2010-01-13T00:00:00-05:00</updated>
   <id>http://matedriven.com.ar/2010/01/13/i-did-it-my-way</id>
   <content type="html">&lt;p style=&quot;padding-right:1em;float:left;&quot;&gt;&lt;a href=&quot;http://www.flickr.com/photos/snippets101/2520125078/&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2047/2520125078_91994868ff_m_d.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://ididitmyway.heroku.com/&quot;&gt;I Did It My Way&lt;/a&gt; is a new blog dedicated entirely to the Sinatra framework. It was created by &lt;a href=&quot;http://twitter.com/daz4126&quot;&gt;Darren Jones&lt;/a&gt; as part of his Sinatra Cookbok project.&lt;/p&gt;
&lt;p&gt;Darren&amp;#8217;s New Year&amp;#8217;s resolution for 2010 is to complete a different Sinatra project every 2 months, so hopefully by the end of this year we will have 6 fully functional Sinatra apps with complete step-by-step guides of how to build them. All applications will be deployed to &lt;a href=&quot;http://heroku.com/&quot;&gt;Heroku&lt;/a&gt; and the code will be publicly available on &lt;a href=&quot;http://github.com/daz4126/&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The first project was &lt;a href=&quot;http://ididitmyway.heroku.com/past/2010/1/10/project_1_reverse/&quot;&gt;just published&lt;/a&gt;, along with an &lt;a href=&quot;http://ididitmyway.heroku.com/past/2010/1/7/please_welcome_sinatra/&quot;&gt;introduction to Sinatra&lt;/a&gt; and a brief tutorial for &lt;a href=&quot;http://ididitmyway.heroku.com/past/2010/1/10/installing_sinatra/&quot;&gt;installing it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Stay tuned for more!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Continuous notification with Integrity</title>
   <link href="http://matedriven.com.ar/2009/09/21/continuous-notification-with-integrity.html"/>
   <updated>2009-09-21T00:00:00-04:00</updated>
   <id>http://matedriven.com.ar/2009/09/21/continuous-notification-with-integrity</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://integrityapp.com/&quot;&gt;Integrity&lt;/a&gt; is a lightweight &lt;a href=&quot;http://en.wikipedia.org/wiki/Continuous_Integration&quot;&gt;Continuous Integration&lt;/a&gt; server written in Ruby. As any other continuous integration server, it can be configured so that as soon as you push your commits, it builds your project, runs your tests, and makes sure everything is still working fine.&lt;/p&gt;
&lt;p&gt;Integrity comes with a simple but powerful notification system that reports the build status to all team members in (optionally) many different ways. Currently there are notifiers available for &lt;a href=&quot;http://github.com/integrity/integrity-email&quot;&gt;Email&lt;/a&gt;, &lt;a href=&quot;http://github.com/hukl/integrity-jabber&quot;&gt;Jabber&lt;/a&gt;, &lt;a href=&quot;http://github.com/integrity/integrity-campfire&quot;&gt;Campfire&lt;/a&gt;, &lt;a href=&quot;http://github.com/integrity/integrity-irc&quot;&gt;&lt;span class=&quot;caps&quot;&gt;IRC&lt;/span&gt;&lt;/a&gt;, &lt;a href=&quot;http://github.com/cwsaylor/integrity-twitter&quot;&gt;Twitter&lt;/a&gt;, &lt;a href=&quot;http://github.com/pyrat/integrity-basecamp&quot;&gt;Basecamp&lt;/a&gt; and &lt;a href=&quot;http://github.com/jstewart/integrity-yammer/tree&quot;&gt;Yammer&lt;/a&gt;, and they are all easy to set up.&lt;/p&gt;
&lt;h3&gt;Setting up a notifier&lt;/h3&gt;
&lt;p&gt;For example, if you want Integrity to send you an email after each build, you can set up the email notifier in 3 simple steps:&lt;/p&gt;
&lt;p&gt;1. Install the notifier gem&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;sudo gem install integrity-email
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;2. Require the notifier in your config.ru file&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;rubygems&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;integrity&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# You need to add the following line:&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;integrity/notifier/email&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;3. Restart Integrity&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s it! Now you can configure the email notifier options for each project on your Integrity installation. The process is exactly the same for all the other notifiers.&lt;/p&gt;
&lt;h3&gt;Creating your own notifiers&lt;/h3&gt;
&lt;p&gt;As you can see, setting up a notifier is easy. But where Integrity&amp;#8217;s notification system really shines is when you start writing your own notifiers.&lt;/p&gt;
&lt;p&gt;Creating a new notifier is really simple. There are just a couple of rules to consider:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;All notifiers are derived from Integrity::Notifier::Base&lt;/li&gt;
	&lt;li&gt;At a minimum, a notifier must implement two methods: &lt;code&gt;to_haml&lt;/code&gt; and &lt;code&gt;deliver!&lt;/code&gt;. The first one must return some markup in haml format that will be rendered on the projects page, and it is useful if your notifier requires some configuration (as most notifiers do). The &lt;code&gt;deliver!&lt;/code&gt; method is where the real action takes place, as this is the method that gets called after Integrity builds a project.&lt;/li&gt;
	&lt;li&gt;Although you can have a notifier working by implementing just these two methods, I would suggest that you also implement the &lt;code&gt;to_s&lt;/code&gt; method in your notifier so that its messages are easily identifiable on Integrity&amp;#8217;s log file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Following these rules, we can create a simple Integrity notifier with just a few lines of code:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;integrity&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Integrity&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Notifier&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Dummy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Notifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_haml&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;deliver!&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;to_s&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&amp;#39;Dummy&amp;#39;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Dummy&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Don&amp;#39;t forget to register your notifier!&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Of course, a notifier like this one does not do anything interesting. All it does is to register itself with the Integrity server and write a message on the log file each time it gets called.&lt;/p&gt;
&lt;h3&gt;A real-life example: the Tumblr notifier&lt;/h3&gt;
&lt;p&gt;Let&amp;#8217;s complicate things a bit more by creating a notifier that will post a message to a tumblelog informing the result of each new build.&lt;/p&gt;
&lt;p&gt;One of the first things we need to decide when we create a new notifier is the info that we want to include in the notifications. All Integrity notifiers get access to the following info by default:&lt;/p&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;th&gt;Method &lt;/th&gt;
		&lt;th&gt;Description &lt;/th&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; short_message &lt;/td&gt;
		&lt;td&gt; A readable status message. E.g. &amp;#8220;Built #{short_identifier} successfully&amp;#8221; &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; full_message &lt;/td&gt;
		&lt;td&gt; A long message containing all the info available for this commit (commit identifier, status, timestamp, author, output, etc.) &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit_url &lt;/td&gt;
		&lt;td&gt; Integrity url corresponding to this commit &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; stripped_commit_output &lt;/td&gt;
		&lt;td&gt; Build output &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;In most cases, that is all you will need. But if you have particular needs and/or prefer to have more control over the info included on your notifications, you could also access the commit object directly:&lt;/p&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;th&gt;Method &lt;/th&gt;
		&lt;th&gt;Description &lt;/th&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.identifier &lt;/td&gt;
		&lt;td&gt; Unique identifier for this commit &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.short_identifier &lt;/td&gt;
		&lt;td&gt; First 7 digits of the unique identifier &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.message &lt;/td&gt;
		&lt;td&gt; Commit message as entered by the author &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.project.name &lt;/td&gt;
		&lt;td&gt; Project&amp;#8217;s name &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.author.name &lt;/td&gt;
		&lt;td&gt; Author&amp;#8217;s name &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.committed_at &lt;/td&gt;
		&lt;td&gt; Timestamp of this commit &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.status &lt;/td&gt;
		&lt;td&gt; Build status. Could be :pending, :success, or :failed &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.successful? &lt;/td&gt;
		&lt;td&gt; True if commit.status == :success, false otherwise &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.pending? &lt;/td&gt;
		&lt;td&gt; True if commit.status == :pending, false otherwise &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.failed? &lt;/td&gt;
		&lt;td&gt; True if commit.status == :failed, false otherwise &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.human_readable_status &lt;/td&gt;
		&lt;td&gt; A readable status message. E.g. &amp;#8220;Built #{short_identifier} successfully&amp;#8221; &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; commit.output &lt;/td&gt;
		&lt;td&gt; Build output. Use stripped_commit_output instead &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;For this notifier I will be using the &lt;code&gt;short_message&lt;/code&gt; as the post&amp;#8217;s title, and the &lt;code&gt;full_message&lt;/code&gt; as the post&amp;#8217;s body. Let&amp;#8217;s see how the code looks like:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# tumblr.rb&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;integrity&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__FILE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/tumblr_client.rb&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Integrity&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Notifier&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tumblr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Notifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
      &lt;span class=&quot;kp&quot;&gt;attr_reader&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:config&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_haml&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__FILE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/config.haml&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;deliver!&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;TumblrClient&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;email&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;short_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;to_s&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&amp;#39;Tumblr&amp;#39;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Tumblr&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;I will also need to provide a configuration form that let us configure both the Tumblr account&amp;#8217;s email address and password:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# config.haml&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;normal&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;tumblr_notifier_email&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Email&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;#tumblr_notifier_email{ :name =&amp;gt; &amp;quot;notifiers[Tumblr][email]&amp;quot;,         |&lt;/span&gt;
                                     &lt;span class=&quot;ss&quot;&gt;:value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;email&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;text&amp;#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;normal&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;tumblr_notifier_password&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Password&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;#tumblr_notifier_password{ :name =&amp;gt; &amp;quot;notifiers[Tumblr][password]&amp;quot;,         |&lt;/span&gt;
                                        &lt;span class=&quot;ss&quot;&gt;:value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;text&amp;#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;I have already created a gem with this code and published it on GitHub. Feel free to install it and play around with it if you want. Just remember the 3 steps:&lt;/p&gt;
&lt;p&gt;1. Install the gem&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;sudo gem install integrity-tumblr
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;2. Require the notifier in your config.ru file&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;integrity/notifier/tumblr&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;3. Restart Integrity and enable notifications via Tumblr for the projects you want&lt;/p&gt;
&lt;h3&gt;Recursive notification&lt;/h3&gt;
&lt;p&gt;Here is the integrity-tumblr notifier notifying me via Tumblr that Integrity has successfully built the integrity-tumblr project itself. Cool!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/29594891@N07/3941167845/&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3519/3941167845_55aa8796cf_o.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Resources:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/matflores/integrity-dummy&quot;&gt;integrity-dummy&lt;/a&gt; notifier source at GitHub.&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/matflores/integrity-tumblr&quot;&gt;integrity-tumblr&lt;/a&gt; notifier source at GitHub.&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Using Git to maintain your blog</title>
   <link href="http://matedriven.com.ar/2009/04/28/using-git-to-maintain-your-blog.html"/>
   <updated>2009-04-28T00:00:00-04:00</updated>
   <id>http://matedriven.com.ar/2009/04/28/using-git-to-maintain-your-blog</id>
   <content type="html">&lt;p&gt;On a &lt;a href=&quot;http://matedriven.com.ar/2009/03/25/getting-started-with-jekyll.html&quot;&gt;previous post&lt;/a&gt; I wrote about installing &lt;a href=&quot;http://qrush.github.com/jekyll/&quot;&gt;Jekyll&lt;/a&gt; and setting up a typical Jekyll-based blog.&lt;/p&gt;
&lt;p&gt;Having my blog generated with a single command was nice, but I still needed something else. What I was looking for was something that worked like &lt;a href=&quot;http://github.com/blog/272-github-pages&quot;&gt;GitHub pages&lt;/a&gt; but on a shared host. In other words, I wanted to be able of writing a new post in my text editor, and then git commit and git push to the server, to see how my blog gets updated without having to do anything else.&lt;/p&gt;
&lt;p&gt;After looking at some alternatives and doing some tests, I ended up implementing a simple solution that involves three Git repositories and some hooks to keep everything in-sync:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;A &lt;em&gt;local&lt;/em&gt; repository containing the blog&amp;#8217;s source files&lt;/li&gt;
	&lt;li&gt;A remote repository replicating the &lt;em&gt;local&lt;/em&gt; repository. Whenever something in the blog changes, I run Jekyll on this repository&amp;#8217;s working tree to generate my site. I will call this the &lt;em&gt;live&lt;/em&gt; repository in the rest of this post.&lt;/li&gt;
	&lt;li&gt;A remote bare repository that acts as an interface between the &lt;em&gt;local&lt;/em&gt; and &lt;em&gt;live&lt;/em&gt; repositories. I guess I could live without this one, but I have read too many stories about issues caused by pushing to a git repository with a working tree attached to it, at least enough to discard the idea of pushing from &lt;em&gt;local&lt;/em&gt; to &lt;em&gt;live&lt;/em&gt; directly. I call this one the &lt;em&gt;base&lt;/em&gt; repository.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On this post I will show you how you can implement this solution in your own host.&lt;/p&gt;
&lt;p&gt;The following steps assume that you already have a vps or shared host account with ssh access enabled and that both git &amp;amp; jekyll are already installed on your server:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Gitify your blog&amp;#8217;s source folder&lt;/li&gt;
	&lt;li&gt;Set up the remote Git repositories&lt;/li&gt;
	&lt;li&gt;Hook everything up&lt;/li&gt;
	&lt;li&gt;Publish your blog&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Gitify your blog&amp;#8217;s source folder&lt;/h3&gt;
&lt;p&gt;The first step is to create a new local Git repository that contains your blog&amp;#8217;s source files. Assuming you already have a Jekyll-compatible folder structure in place, all you need to do is this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/my_jekyll_blog_folder
git init
git add .
git commit -m &lt;span class=&quot;s2&quot;&gt;&amp;quot;Initial blog setup&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Replace &lt;code&gt;my_jekyll_blog_folder&lt;/code&gt; with your own folder name, of course.&lt;/p&gt;
&lt;p&gt;If you do not have a Jekyll-compatible folder tree yet, take a look at &lt;a href=&quot;http://matedriven.com.ar/2009/03/25/getting-started-with-jekyll.html&quot;&gt;Getting started with Jekyll&lt;/a&gt; for more details.&lt;/p&gt;
&lt;h3&gt;Setting up the remote Git repositories&lt;/h3&gt;
&lt;p&gt;Now that the &lt;em&gt;local&lt;/em&gt; repository is ready, the next step is to create and configure the two remote Git repositories on your shared/vps host. First, let&amp;#8217;s create the &lt;em&gt;base&lt;/em&gt; repository by opening a ssh session on your host and executing the following:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;mkdir -p ~/git/base.git
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/git/base.git
git --bare init
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The &lt;em&gt;base&lt;/em&gt; repository will serve as an interface between &lt;em&gt;local&lt;/em&gt; and &lt;em&gt;live&lt;/em&gt; repositories, so now you need to add &lt;em&gt;base&lt;/em&gt; as a remote repository to the &lt;em&gt;local&lt;/em&gt; repository. To do this, go to your local pc (leave the ssh session open, as we are going to get back there soon) and execute the following:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;git remote add server ssh://you@yourdomain.com/~/git/base.git
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Also, edit your .git/config file in the &lt;em&gt;local&lt;/em&gt; repository and add the following:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;branch &lt;span class=&quot;s2&quot;&gt;&amp;quot;master&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;remote&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; server
  &lt;span class=&quot;nv&quot;&gt;merge&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; refs/heads/master
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Creating the &lt;em&gt;live&lt;/em&gt; repository is even easier than &lt;em&gt;base&lt;/em&gt;, as you can clone the bare repository created before. Notice that git &amp;lt; 1.6.2 will not allow you to clone an empty repository, and therefore you must push something to &lt;em&gt;base&lt;/em&gt; first. From your local repository:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;git push server master
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Now we can switch to the ssh session and create the &lt;em&gt;live&lt;/em&gt; repository by cloning &lt;em&gt;base&lt;/em&gt; as usual:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/git
git clone base.git live
&lt;/pre&gt;
&lt;/div&gt;&lt;h3&gt;Hooking everything up&lt;/h3&gt;
&lt;p&gt;Ok, we are almost done with this. Let&amp;#8217;s add some git hooks to automate the process of generating the site each time we push something to the &lt;em&gt;base&lt;/em&gt; repository. To do this, cd to the ~/git/base.git/hooks directory on your server and edit the post-update file with the following contents:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*** Updating live repository ***&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/git/live &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;unset &lt;/span&gt;GIT_DIR
git pull origin master

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*** Generating site with Jekyll ***&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/gems/bin/jekyll

&lt;span class=&quot;nb&quot;&gt;exec &lt;/span&gt;git-update-server-info
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;This script will be executed every time the &lt;em&gt;base&lt;/em&gt; repository gets updated. It cd&amp;#8217;s to the &lt;em&gt;live&lt;/em&gt; repository, pulls the changes from &lt;em&gt;base&lt;/em&gt; and finally run Jekyll to re-generate the whole site.&lt;/p&gt;
&lt;p&gt;Notice that you need to replace &lt;code&gt;$HOME/gems/bin/jekyll&lt;/code&gt; by the appropriate command to execute Jekyll on your own hosted account.&lt;/p&gt;
&lt;p&gt;That would be all you need for having a similar workflow than the one used by GitHub pages. But just to be sure that both remote repositories are in-sync all the time, I added the following script to the &lt;em&gt;live&lt;/em&gt; repository to push any commited changes back up to &lt;em&gt;base&lt;/em&gt; after every commit in &lt;em&gt;live&lt;/em&gt;. Put this content into the ~/git/live/.git/hooks/post-commit file:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*** Pushing changes to base repository ***&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;

git push origin master
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;In practice I try to avoid editing files directly on the &lt;em&gt;live&lt;/em&gt; repository, but this script makes sure that both remote repositories still get synchronized in case I ever need to do that.&lt;/p&gt;
&lt;p&gt;Remember to make those scripts executable:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;chmod +x ~/git/base.git/hooks/post-update
chmod +x ~/git/live/.git/hooks/post-commit
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Otherwise the git hooks will not work.&lt;/p&gt;
&lt;h3&gt;Publish your Jekyll-powered blog&lt;/h3&gt;
&lt;p&gt;Now that we are ready, let&amp;#8217;s replace your current html directory with the output generated by Jekyll. On the server:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~
mv public_html public_html.old
ln -s ~/git/live/_site public_html
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Remember to replace &lt;code&gt;public_html&lt;/code&gt; above with your actual html directory (&lt;code&gt;html&lt;/code&gt;, &lt;code&gt;/var/www&lt;/code&gt;, etc.).&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;That is it. You can now start writing your posts on your local _posts directory. Whenever you are ready, all you need to do in order to update your blog online is executing the following:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;git commit -am &lt;span class=&quot;s2&quot;&gt;&amp;quot;New post: Using Git to maintain your blog&amp;quot;&lt;/span&gt;
git push
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The git hooks will take care of synchronizing the &lt;em&gt;live&lt;/em&gt; repository and re-generating your blog with Jekyll.&lt;/p&gt;
&lt;p&gt;Happy blogging!&lt;/p&gt;
&lt;p&gt;Resources:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;The original Git workflow on which I based mine can be found at &lt;a href=&quot;http://joemaller.com/2008/11/25/a-web-focused-git-workflow&quot;&gt;A web-focused Git workflow&lt;/a&gt; by Joe Maller.&lt;/li&gt;
	&lt;li&gt;Daniel Miessler wrote another post on this topic, using a similar approach: &lt;a href=&quot;http://dmiessler.com/blog/using-git-to-maintain-your-website&quot;&gt;Using Git to maintain your website&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;For more details on creating a private Git repository on your shared host account, take a look at John Nunemaker&amp;#8217;s &lt;a href=&quot;http://railstips.org/2008/11/24/gitn-your-shared-host-on&quot;&gt;Git&amp;#8217;n your shared host on&lt;/a&gt; article.&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Getting started with Jekyll</title>
   <link href="http://matedriven.com.ar/2009/03/25/getting-started-with-jekyll.html"/>
   <updated>2009-03-25T00:00:00-04:00</updated>
   <id>http://matedriven.com.ar/2009/03/25/getting-started-with-jekyll</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt; is a simple static site generator created by &lt;a href=&quot;http://tom.preston-werner.com/&quot;&gt;Tom Preston-Werner&lt;/a&gt; that is used as the engine behind the well-known &lt;a href=&quot;http://pages.github.com/&quot;&gt;GitHub Pages&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I must admit that the first time I heard about this, the idea did not grab my attention at all. But after reading &lt;a href=&quot;http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html&quot;&gt;some&lt;/a&gt; &lt;a href=&quot;http://jarinheit.com/2009/02/16/simplified-blogging-with-github-pages-and-jekyll.html&quot;&gt;inspiring&lt;/a&gt; &lt;a href=&quot;http://blog.new-bamboo.co.uk/2009/2/20/migrating-from-mephisto-to-jekyll&quot;&gt;blog&lt;/a&gt; &lt;a href=&quot;http://metajack.im/2009/01/23/blogging-with-git-emacs-and-jekyll/&quot;&gt;posts&lt;/a&gt; about it, everything started to make sense and I decided to give it a try on my new blog, and so far, I like it.&lt;/p&gt;
&lt;h3&gt;Installing Jekyll&lt;/h3&gt;
&lt;p&gt;The easiest way to install Jekyll is via RubyGems:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;sudo gem install jekyll
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Notice that Jekyll requires directory_watcher, liquid, open4 and maruku. They will be automatically installed by the gem install command.&lt;/p&gt;
&lt;h3&gt;Creating content&lt;/h3&gt;
&lt;p&gt;Basically, what Jekyll does is to take several &lt;a href=&quot;http://www.textism.com/tools/textile/&quot;&gt;.textile&lt;/a&gt; or &lt;a href=&quot;http://daringfireball.net/projects/markdown/&quot;&gt;.markdown&lt;/a&gt; files and translates them into html, optionally using layout templates to avoid duplicating the common areas of our blog on each post. So, all we need to do is place our own content files in the correct locations.&lt;/p&gt;
&lt;p&gt;A typical Jekyll blog setup would be as follows:&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;An &lt;code&gt;index.html&lt;/code&gt; file on the root directory that will serve as the home page of our blog.&lt;/li&gt;
	&lt;li&gt;One or more template layouts in the &lt;code&gt;_layouts&lt;/code&gt; directory. These layouts can then be referenced from any other file by using the layout attribute in the &lt;span class=&quot;caps&quot;&gt;YAML&lt;/span&gt; header. Also notice that layouts can be nested.&lt;/li&gt;
	&lt;li&gt;One .textile or .markdown file for each post in the &lt;code&gt;_posts&lt;/code&gt; directory.&lt;/li&gt;
	&lt;li&gt;One .textile or .markdown file for each draft in the &lt;code&gt;_drafts&lt;/code&gt; directory. Any posts in this directory will be ignored by Jekyll at generation time.&lt;/li&gt;
	&lt;li&gt;One or more .textile or .markdown files in the &lt;code&gt;_includes&lt;/code&gt; directory. Any files located in this directory can be included into another file with the &lt;code&gt;include&lt;/code&gt; tag.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a starting point, you might want to take a look at Tom Preston-Werner&amp;#8217;s &lt;a href=&quot;http://github.com/mojombo/tpw&quot;&gt;&lt;span class=&quot;caps&quot;&gt;TPW&lt;/span&gt;&lt;/a&gt; repository.&lt;/p&gt;
&lt;h3&gt;Generating the blog&lt;/h3&gt;
&lt;p&gt;Once that the basic layout and content of our blog was set up, we are ready for telling Jekyll to generate our site:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;jekyll
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;If everything goes well, by now we should have our brand new Jekyll-powered blog generated on the &lt;code&gt;_site&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;We can also run Jekyll with the &lt;code&gt;--server&lt;/code&gt; flag in order to test the generated site:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;jekyll --server
&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;This flag tells Jekyll to launch a WEBrick server instance. Now we can point our web browser to &lt;code&gt;http://localhost:4000&lt;/code&gt; and test the generated site locally.&lt;/p&gt;
&lt;h3&gt;Publishing everything&lt;/h3&gt;
&lt;p&gt;At this point, we can just ftp the contents of the &lt;code&gt;_site&lt;/code&gt; directory to our web site and we&amp;#8217;re done.&lt;/p&gt;
&lt;p&gt;However, a much better solution would be to create a remote git repository and add some git hooks there that take care of generating the site for us each time we do a simple &lt;code&gt;git push&lt;/code&gt;. That is exactly the setup I am using to maintain this blog, and I will be writing about it in a future post.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This solution is definitely not for everyone. But if you are a programmer, and especially if you spend most of your day working with a text editor and a terminal window opened, then you may find the combination of Jekyll, Git, and your editor of choice (vim, in my case, but Emacs, TextMate or any other would work just fine, of course) more appealing than any traditional blog software.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Should be or should_not be...</title>
   <link href="http://matedriven.com.ar/2009/03/20/should-be-or-should-not-be.html"/>
   <updated>2009-03-20T00:00:00-04:00</updated>
   <id>http://matedriven.com.ar/2009/03/20/should-be-or-should-not-be</id>
   <content type="html">&lt;p&gt;I found this nice piece of Ruby poetry today on the rspec-users mailing list, and I thought it would be nice to pass it along.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;should be || should_not be: that is the expectation:&lt;br /&gt;
Whether &amp;#8216;tis nobler in the parser to interpret&lt;br /&gt;
The outputs and side effects of outrageous duck typing,&lt;br /&gt;
Or to inherit against a sea of matchers&lt;br /&gt;
And by declaration extend them?  To fail: to raise;&lt;br /&gt;
No more; and by a raise to say we throw&lt;br /&gt;
The exception and the thousand natural returns&lt;br /&gt;
The code is heir to, &amp;#8217;tis a specification&lt;br /&gt;
Devoutly to be wished.  To fail: to raise;&lt;br /&gt;
To raise, perchance to rescue: ay, there&amp;#8217;s the rub,&lt;br /&gt;
For in that state of exception what tests may fail&lt;br /&gt;
When we have injected in this matcher code&lt;br /&gt;
Must give us pause: there&amp;#8217;s the RSpec&lt;br /&gt;
That makes calamity of such long backtraces;&lt;br /&gt;
For who would bear the Flogs and Heckles,&lt;br /&gt;
The oppressor&amp;#8217;s Reek, the proud man&amp;#8217;s Cucumber,&lt;br /&gt;
The pangs of despised Rcov, the spec_server&amp;#8217;s Drb,&lt;br /&gt;
The insolence of Autotest and the spurns&lt;br /&gt;
That patient merit of the occasional Rakes,&lt;br /&gt;
When he himself might his validation make&lt;br /&gt;
With a bare assertion?&amp;#8230; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;padding-right:33em;text-align:right;&quot;&gt;&amp;#8212; &lt;a href=&quot;http://extraneous.org/&quot;&gt;Stephen Eley&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 
</feed>
