<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

 <title>William Durand</title>
 
 <link href="http://www.williamdurand.fr/" />
 <updated>2012-05-29T10:54:51-07:00</updated>
 <id>http://www.williamdurand.fr/</id>
 <author>
   <name>William Durand</name>
   <email>william.durand1@gmail.com</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/WilliamDurand" /><feedburner:info uri="williamdurand" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>Propel, And Symfony2 A Year Ago</title>
   <link href="http://feedproxy.google.com/~r/WilliamDurand/~3/S2WcnioSpjg/" />
   <updated>2012-04-25T00:00:00-07:00</updated>
   <id>http://www.williamdurand.fr/2012/04/25/propel-and-symfony2-a-year-ago</id>
   <content type="html">&lt;p&gt;Did you know that the &lt;a href='http://github.com/propelorm/PropelBundle'&gt;PropelBundle&lt;/a&gt; was part of the Symfony2 core? Yes, at the very beginning, and it has been dropped after. So basically, I didn&amp;#8217;t create the PropelBundle but started to learn Symfony2 by using it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hi,&lt;/p&gt;

&lt;p&gt;You seem to work on the PropelBundle actively, and that&amp;#8217;s great news. This bundle is under my account right now because it is orphan. But if you want to take care of the maintenance of it, then I think it&amp;#8217;s time for your fork to become the official repository for the bundle. What do you think?&lt;/p&gt;

&lt;p&gt;Fabien&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To be honest, this bundle didn&amp;#8217;t really work, and I spent a lot of time to both learn Symfony2 internals, Propel 1.6 internals, and how to fix this bundle. It was fun. After few weeks, the bundle became interesting to use, and in the same time, I joined e-TF1 where I had the opportunity to work with both Symfony2, and Propel, for real.&lt;/p&gt;

&lt;p&gt;Few months later, I decided to take the lead of the Propel project, and I added the PropelBundle as an official Propel project. It was the best choice because people helped me a lot to improve this bundle, and now it is fully compatible with Symfony2 (kudos to &lt;a href='https://github.com/havvg'&gt;Toni&lt;/a&gt;, the PropelBundle manager). To spread the word, I also wrote quite complete &lt;a href='http://www.propelorm.org/documentation/#working_with_symfony2'&gt;documentation about Propel, and Symfony2&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To be reliable was the hardest part of the work, even if the bundle worked great, and even if we were there to answer questions, or to fix issues. That&amp;#8217;s why I asked Fabien to create a &lt;a href='https://github.com/symfony/Propel1Bridge'&gt;Propel Bridge&lt;/a&gt; in Symfony2. It was the first step to avoid comments like &amp;#8220;it&amp;#8217;s not the default ORM, lalala&amp;#8221;. In the same time, Symfony2 took the decision to be a &lt;em&gt;View Controller&lt;/em&gt; Framework, without any &lt;em&gt;Model&lt;/em&gt; layer bundled by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Today&lt;/strong&gt;, I&amp;#8217;m proud to announce that the last step has been unlocked thanks to &lt;a href='https://github.com/rouffj'&gt;Joseph&lt;/a&gt;. &lt;strong&gt;Propel has its own &lt;a href='http://symfony.com/doc/master/book/propel.html'&gt;chapter in the official Symfony2 book&lt;/a&gt;&lt;/strong&gt; which means you have to think about which &lt;em&gt;Model&lt;/em&gt; layer to use now. No more excuse to not try Propel in Symfony2, or to use Doctrine2 by default, and not by choice.&lt;/p&gt;

&lt;p&gt;Try Propel, really! It could fit your needs depending on what you expect. Some great bundles already support Propel (like the FOSUserBundle). And please, avoid comments like &amp;#8220;Doctrine2 is much nicer&amp;#8221; which make no sense. Why is it much nicer? I never got any good arguments in favor of Doctrine2 I didn&amp;#8217;t already know by myself. I can hear everything which is constructive. I used Doctrine2 for more than six months, both ORM, and ODM (MongoDB). I have strong arguments against it, but I also like some parts of it. Who can say the same thing about Propel?&lt;/p&gt;

&lt;p&gt;Now, you have the choice, it&amp;#8217;s up to you! But, give Propel a chance before to complain about it, or to comment it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/WilliamDurand/~4/S2WcnioSpjg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://www.williamdurand.fr/2012/04/25/propel-and-symfony2-a-year-ago/</feedburner:origLink></entry>
 
 <entry>
   <title>I Will Be Speaking At Symfony Live 2012</title>
   <link href="http://feedproxy.google.com/~r/WilliamDurand/~3/S0R_Kpcm0TI/" />
   <updated>2012-04-11T00:00:00-07:00</updated>
   <id>http://www.williamdurand.fr/2012/04/11/i-will-be-speaking-at-symfony-live-2012</id>
   <content type="html">&lt;p&gt;Heya, I&amp;#8217;m glad to announce that I will be speaking at &lt;a href='http://paris2012.live.symfony.com/'&gt;Symfony Live 2012&lt;/a&gt; in Paris, on 7-8th of June.&lt;/p&gt;

&lt;p&gt;I will speak about &lt;a href='http://github.com/propelorm/Propel2'&gt;Propel2&lt;/a&gt;, the upcoming version of &lt;a href='http://www.propelorm.org'&gt;Propel ORM&lt;/a&gt;. It will probably present the Propel philosophy, how it works in real life, how it&amp;#8217;s built, and some other parts you will discover.&lt;/p&gt;

&lt;p&gt;To be honest, it will be my very first conference talk, so I decided to speak in French. Even if some people complained about that, I&amp;#8217;m not yet comfortable with my English to hold a talk in English. But, I will write my slides in English. That way, it will be quite easy to understand for people who don&amp;#8217;t understand French.&lt;/p&gt;

&lt;p&gt;Hope to see you there.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/WilliamDurand/~4/S0R_Kpcm0TI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://www.williamdurand.fr/2012/04/11/i-will-be-speaking-at-symfony-live-2012/</feedburner:origLink></entry>
 
 <entry>
   <title>Crazy Idea #1: Converting My Blog Posts In Audio Files</title>
   <link href="http://feedproxy.google.com/~r/WilliamDurand/~3/_iwI4IiAxk0/" />
   <updated>2012-02-29T00:00:00-08:00</updated>
   <id>http://www.williamdurand.fr/2012/02/29/crazy-idea-1-converting-my-blog-posts-in-audio-files</id>
   <content type="html">&lt;p&gt;Yesterday, I discovered the &lt;code&gt;say&lt;/code&gt; command on my Mac. Its aim is to convert text to audible speech, and it works really well. Then, I had the idea to create audio files from my blog posts, because it&amp;#8217;s fun, and because it could improve accessibility.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;say&lt;/code&gt; command generates &lt;code&gt;aiff&lt;/code&gt; audio files, which is not really understandable by the &lt;code&gt;audio&lt;/code&gt; html5 tag. So, I had to convert this output in a &lt;code&gt;mp3&lt;/code&gt; file. I used the well-known &lt;a href='http://ffmpeg.org/'&gt;ffmpeg&lt;/a&gt; tool, and that&amp;#8217;s all!&lt;/p&gt;

&lt;p&gt;Please, welcome &lt;a href='https://github.com/willdurand/Speaker'&gt;Speaker&lt;/a&gt;, my fun work of last evening. &lt;strong&gt;Speaker&lt;/strong&gt; aims to convert my blog posts in markdown syntax to a &lt;code&gt;mp3&lt;/code&gt; file. This is a tiny shell script I enjoyed to write.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;USAGE:
  ./speaker &lt;span class='o'&gt;[&lt;/span&gt;-h&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;-d &amp;lt;output directory&amp;gt;&lt;span class='o'&gt;]&lt;/span&gt; &amp;lt;filename&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I used &lt;a href='http://bmizerany.github.com/roundup/'&gt;roundup&lt;/a&gt; to test it. I love shell scripts, but to write them without any tests is a pain, there is often a condtion which is not good, a typo, or something else. That often makes me crazy! &lt;strong&gt;roundup&lt;/strong&gt; helps you write strong shell scripts. Here is my test suite output:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;./speaker-test.sh
speaker
it_shows_help_with_no_argv:                      &lt;span class='o'&gt;[&lt;/span&gt;PASS&lt;span class='o'&gt;]&lt;/span&gt;
it_shows_help_with_h_option:                     &lt;span class='o'&gt;[&lt;/span&gt;PASS&lt;span class='o'&gt;]&lt;/span&gt;
it_creates_mp3_file:                             &lt;span class='o'&gt;[&lt;/span&gt;PASS&lt;span class='o'&gt;]&lt;/span&gt;
it_creates_mp3_file_in_existing_directory:       &lt;span class='o'&gt;[&lt;/span&gt;PASS&lt;span class='o'&gt;]&lt;/span&gt;
it_creates_mp3_file_in_new_directory:            &lt;span class='o'&gt;[&lt;/span&gt;PASS&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='o'&gt;=========================================================&lt;/span&gt;
Tests:    5 | Passed:   5 | Failed:   0
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;To sanitize the text to speech, I used some regular expressions. It probably needs some improvements but it works pretty well:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='c'&gt;# Sanitize markdown content&lt;/span&gt;
&lt;span class='nv'&gt;content&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='sb'&gt;`&lt;/span&gt;&lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;$content&amp;quot;&lt;/span&gt; | sed -e &lt;span class='s1'&gt;&amp;#39;s/[\*_]//g&amp;#39;&lt;/span&gt;&lt;span class='sb'&gt;`&lt;/span&gt;
&lt;span class='nv'&gt;content&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='sb'&gt;`&lt;/span&gt;&lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;$content&amp;quot;&lt;/span&gt; | sed -e &lt;span class='s1'&gt;&amp;#39;s/\[\(.*\)\](\(.*\))/\1/g&amp;#39;&lt;/span&gt;&lt;span class='sb'&gt;`&lt;/span&gt;
&lt;span class='nv'&gt;content&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='sb'&gt;`&lt;/span&gt;&lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;$content&amp;quot;&lt;/span&gt; | sed -e &lt;span class='s1'&gt;&amp;#39;s/:[p|D]/./g&amp;#39;&lt;/span&gt;&lt;span class='sb'&gt;`&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;For the other parts, check &lt;a href='https://github.com/willdurand/Speaker/blob/master/speaker'&gt;the code&lt;/a&gt; :)&lt;/p&gt;

&lt;p&gt;As I wanted to provide my blog posts as audio files, I tweaked my templates to integrate an &lt;code&gt;audio&lt;/code&gt; html5 tag. And I used &lt;a href='https://github.com/etianen/html5media'&gt;html5media&lt;/a&gt; to render this tag in all major browsers (don&amp;#8217;t know if there is a better solution).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='nt'&gt;&amp;lt;audio&lt;/span&gt; &lt;span class='na'&gt;src=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;/mp3/my-blog-title.mp3&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;controls&lt;/span&gt; &lt;span class='na'&gt;preload&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&amp;lt;/audio&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And to automagically generate audio files, I wrote a &lt;a href='https://github.com/willdurand/Speaker/blob/master/hooks/pre-commit'&gt;pre-commit&lt;/a&gt; script to build the audio file when I commit blog posts. That&amp;#8217;s all folks!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/WilliamDurand/~4/_iwI4IiAxk0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://www.williamdurand.fr/2012/02/29/crazy-idea-1-converting-my-blog-posts-in-audio-files/</feedburner:origLink></entry>
 
 <entry>
   <title>Deploying With Git</title>
   <link href="http://feedproxy.google.com/~r/WilliamDurand/~3/qXHbwffy41A/" />
   <updated>2012-02-25T00:00:00-08:00</updated>
   <id>http://www.williamdurand.fr/2012/02/25/deploying-with-git</id>
   <content type="html">&lt;p&gt;Yeah, I know yet another blog post on this topic. The main difference with others is that I wrote it myself, and it&amp;#8217;s quite up to date :p&lt;/p&gt;

&lt;p&gt;I often rely on &lt;a href='https://github.com/capistrano/capistrano/wiki/'&gt;Capistrano&lt;/a&gt; to deploy web applications. I ever talked about this tool &lt;a href='http://www.willdurand.fr/deploiement-automatise-avec-capistrano-et-git-pour-symfony-et-diem/'&gt;in my previous blog&lt;/a&gt;, and it&amp;#8217;s not the purpose of this article.&lt;/p&gt;

&lt;p&gt;Actually, when you need to deploy a simple web application on a server, like this blog for instance, there is no need to use Capistrano or &lt;a href='http://docs.fabfile.org/en/1.4.0/index.html'&gt;Fabric&lt;/a&gt;. You just need to copy files. So you could rely on &lt;code&gt;rsync&lt;/code&gt;&amp;#8230; But it&amp;#8217;s not fun!&lt;/p&gt;

&lt;p&gt;Actually, you just need to rely on &lt;strong&gt;Git&lt;/strong&gt;, assuming you are using it.&lt;/p&gt;

&lt;p&gt;The first step is to configure your local repository by adding a new remote:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git remote add -t master production ssh://&amp;lt;server&amp;gt;/path/to/project_prod&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;-t &amp;lt;branch&amp;gt;&lt;/code&gt; option allows you to track a given branch instead of all branches. You can add more remotes if you want like a &lt;code&gt;testing&lt;/code&gt; remote.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git remote add testing ssh://&amp;lt;server&amp;gt;/path/to/project_test&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To deploy the application in &lt;strong&gt;production&lt;/strong&gt;, run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git push production&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And, to deploy in a &lt;strong&gt;testing&lt;/strong&gt; environment, just run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git push testing &amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can push your code on your server, but it won&amp;#8217;t deploy new changes at the moment. So let&amp;#8217;s configuring &lt;strong&gt;Git&lt;/strong&gt;. First, add the following lines to your &lt;code&gt;.git/config&lt;/code&gt; file:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='o'&gt;[&lt;/span&gt;receive&lt;span class='o'&gt;]&lt;/span&gt;
    &lt;span class='nv'&gt;denyCurrentBranch&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It allows to push code on the current branch, it&amp;#8217;s important to deploy new changes. Old Git versions don&amp;#8217;t need to set this parameter by the way.&lt;/p&gt;

&lt;p&gt;Then, enable a &lt;code&gt;post-receive&lt;/code&gt; hook with the following content:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='c'&gt;#!/bin/sh&lt;/span&gt;

&lt;span class='nv'&gt;SUBJECT&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Deploy successful&amp;quot;&lt;/span&gt;
&lt;span class='nv'&gt;BODY&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;You&amp;#39;ve successfully deployed the branch:&amp;quot;&lt;/span&gt;

&lt;span class='k'&gt;while &lt;/span&gt;&lt;span class='nb'&gt;read &lt;/span&gt;oldrev newrev ref
&lt;span class='k'&gt;do&lt;/span&gt;
&lt;span class='k'&gt;    &lt;/span&gt;&lt;span class='nv'&gt;branch&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='sb'&gt;`&lt;/span&gt;&lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='nv'&gt;$ref&lt;/span&gt; | cut -d/ -f3&lt;span class='sb'&gt;`&lt;/span&gt;

    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;$branch&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;]&lt;/span&gt; ; &lt;span class='k'&gt;then&lt;/span&gt;
&lt;span class='k'&gt;        &lt;/span&gt;&lt;span class='nb'&gt;cd&lt;/span&gt; ..
        env -i git checkout &lt;span class='nv'&gt;$branch&lt;/span&gt;
        env -i git reset --hard

        &lt;span class='nv'&gt;EMAIL&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='sb'&gt;`&lt;/span&gt;env -i git log -1 --format&lt;span class='o'&gt;=&lt;/span&gt;format:%ae HEAD&lt;span class='sb'&gt;`&lt;/span&gt;
        &lt;span class='nv'&gt;BODY&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;$BODY $branch.&amp;quot;&lt;/span&gt;

        &lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;$BODY&amp;quot;&lt;/span&gt; | mail -s &lt;span class='s2'&gt;&amp;quot;$SUBJECT&amp;quot;&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;$EMAIL&amp;quot;&lt;/span&gt;
    &lt;span class='k'&gt;fi&lt;/span&gt;
&lt;span class='k'&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This script updates the working tree after changes have been pushed, and send an email to the last committer. Keep in mind that it always deploys the last branch you push.&lt;/p&gt;

&lt;p&gt;The important part is:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nb'&gt;cd&lt;/span&gt; ..
env -i git checkout &lt;span class='nv'&gt;$branch&lt;/span&gt;
env -i git reset --hard
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Feel free to decorate these three lines as you want.&lt;/p&gt;

&lt;p&gt;In a &lt;strong&gt;production&lt;/strong&gt; environment, or because you are using a &lt;a href='/2012/01/17/my-git-branching-model/'&gt;Git Branching Model&lt;/a&gt;, you should modify the previous code as below. It ensures to always deploy the &lt;code&gt;master&lt;/code&gt; branch:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;$branch&amp;quot;&lt;/span&gt;  &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;master&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;]&lt;/span&gt; ; &lt;span class='k'&gt;then&lt;/span&gt;
&lt;span class='k'&gt;        &lt;/span&gt;&lt;span class='nb'&gt;cd&lt;/span&gt; ..
        env -i git reset --hard

        // Send an email
    &lt;span class='k'&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You&amp;#8217;re done, each time you&amp;#8217;ll run a &lt;code&gt;git push production&lt;/code&gt;, you&amp;#8217;ll deploy your application in production.&lt;/p&gt;

&lt;p&gt;Easy. Fast. Powerful.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/WilliamDurand/~4/qXHbwffy41A" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://www.williamdurand.fr/2012/02/25/deploying-with-git/</feedburner:origLink></entry>
 
 <entry>
   <title>Why You Should Love Code Generation</title>
   <link href="http://feedproxy.google.com/~r/WilliamDurand/~3/Y5sZ0-DQ0AU/" />
   <updated>2012-02-06T00:00:00-08:00</updated>
   <id>http://www.williamdurand.fr/2012/02/06/why-you-should-love-code-generation</id>
   <content type="html">&lt;p&gt;What a nice title, &lt;em&gt;right?&lt;/em&gt; I often see people complain about &lt;strong&gt;code generation&lt;/strong&gt;, and I would like to explain my point of view in a pragmatic approach. As you may know, I&amp;#8217;m the lead developer of &lt;a href='http://propelorm.org/'&gt;Propel&lt;/a&gt;, a great PHP5 &lt;a href='http://en.wikipedia.org/wiki/Object-relational_mapping'&gt;ORM&lt;/a&gt; which uses code generation a lot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code generation&lt;/strong&gt; is about to use &lt;strong&gt;code to write code&lt;/strong&gt;. Pretty easy, &lt;em&gt;isn&amp;#8217;t it?&lt;/em&gt; In &lt;a href='http://github.com/propelorm/Propel2'&gt;Propel2&lt;/a&gt;, we will use &lt;a href='http://twig.sensiolabs.org/'&gt;Twig&lt;/a&gt; to generate PHP code for instance. The golden rule is to &lt;strong&gt;never use the same programming language you want to generate&lt;/strong&gt;, otherwise it will be a pain to maintain (try to read Propel 1.6 builders). But in order to generate code, we need to know information that describe the code we want to generate. The term &lt;strong&gt;metadata&lt;/strong&gt; defines these information. A &lt;em&gt;metadata&lt;/em&gt; is a data about data, that&amp;#8217;s exactly what we need!&lt;/p&gt;

&lt;p&gt;In Propel, the &lt;code&gt;schema.xml&lt;/code&gt; (a &lt;em&gt;XML&lt;/em&gt; file) contains all metadata we need to generate both &lt;em&gt;PHP&lt;/em&gt; and &lt;em&gt;SQL&lt;/em&gt; code. As Propel is an ORM, data will be a database name, tables, columns, primary keys, etc. This is &lt;strong&gt;your business model&lt;/strong&gt;! We can call it a &lt;strong&gt;Platform Independent Model&lt;/strong&gt; (PIM) because this schema is database vendor &lt;strong&gt;agnostic&lt;/strong&gt;. It doesn&amp;#8217;t know anything about &lt;em&gt;MySQL&lt;/em&gt;, &lt;em&gt;Oracle&lt;/em&gt;, or whatever you want. It just describes your model with its own notation.&lt;/p&gt;

&lt;p&gt;To generate code, Propel relies on &lt;strong&gt;builders&lt;/strong&gt; and &lt;strong&gt;platforms&lt;/strong&gt;. &lt;strong&gt;Builders&lt;/strong&gt; own the logic to write &lt;em&gt;PHP&lt;/em&gt; code, and &lt;strong&gt;Platforms&lt;/strong&gt; contain the logic for each database vendor (whether to quote table names or not for instance). This is specific, &lt;em&gt;right?&lt;/em&gt; So let&amp;#8217;s call this layer a &lt;strong&gt;Platform Specific Model&lt;/strong&gt; (PSM).&lt;/p&gt;

&lt;p&gt;Propel uses both a &lt;strong&gt;PIM&lt;/strong&gt; and a &lt;strong&gt;PSM&lt;/strong&gt; to generate code. Actually, it uses the &lt;strong&gt;PIM&lt;/strong&gt; to drive the &lt;strong&gt;PSM&lt;/strong&gt; which depends on configuration parameters also known as &lt;em&gt;build properties&lt;/em&gt; in Propel terminology. That&amp;#8217;s all, here is how Propel works at buildtime :-)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But wait, what?&lt;/em&gt; It&amp;#8217;s all about &lt;a href='http://www.ibm.com/developerworks/rational/library/3100.html'&gt;&lt;strong&gt;Model Driven Architecture&lt;/strong&gt;&lt;/a&gt;! Did you ever hear about that? It&amp;#8217;s the state of the art in research in Computer Science (at least in France). This is a software design approach for the development of applications.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://www.leonardi-free.org/wp-content/uploads/2011/02/model-driven-engineering-schema-en.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;But this is a formal approach, and I would like to keep a pragmatic mind here through Propel. Then, what I love in &lt;strong&gt;code generation&lt;/strong&gt; is that your code is &lt;strong&gt;easily debuggable&lt;/strong&gt;, you can read it, and learn from it. Few years ago, generated code was a mess, especially in &lt;em&gt;symfony 1.x&lt;/em&gt;, but today we are able to generate clean code, as you could write yourself. And, as you write code to generate code, you can test both, and avoid more errors. To generate code &lt;strong&gt;speeds up your application&lt;/strong&gt;, and you can &lt;strong&gt;pre-calculate&lt;/strong&gt; some parts of your code. In Propel (again), we are able to &lt;strong&gt;pre-generate&lt;/strong&gt; &lt;em&gt;SQL&lt;/em&gt; statements at buildtime. That way, we by-pass the need to generate &lt;em&gt;SQL&lt;/em&gt; code at runtime. It&amp;#8217;s really really faster than to use the whole Propel stack.&lt;/p&gt;

&lt;p&gt;In Propel, we also have &lt;em&gt;behaviors&lt;/em&gt;. This is a self-contained logic which extends the current implementation by using hooks at buildtime. A behavior is reusable, testable, and easy to write. Then, you can adopt a &lt;a href='http://propel.posterous.com/behavior-driven-development'&gt;behavior driven development&lt;/a&gt;: write behaviors you will reuse in order to avoid code duplication.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://4.bp.blogspot.com/_Ln5yflq9tNw/STU5TRYvU9I/AAAAAAAAABo/lujbozAii1E/s320/software_management_2.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;I know there are drawbacks to use code generation, especially the need to generate code before to deploy your application in production, or the lack of implementation details. But, for the most part of an application, to generate code helps a lot, and it helps you to get what you really want to get too.&lt;/p&gt;

&lt;p&gt;Tu sum up, &lt;strong&gt;code generation&lt;/strong&gt; is not a crazy idea. It&amp;#8217;s close to MDA, it has pros and cons but in my opinion, code generation is definitely &lt;strong&gt;not&lt;/strong&gt; a bad practice, and you should use it instead of relying on &lt;em&gt;in memory&lt;/em&gt; code or complex architectures just to avoid generation.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/WilliamDurand/~4/Y5sZ0-DQ0AU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://www.williamdurand.fr/2012/02/06/why-you-should-love-code-generation/</feedburner:origLink></entry>
 
 <entry>
   <title>Component Driven Development: it's like Lego!</title>
   <link href="http://feedproxy.google.com/~r/WilliamDurand/~3/4I55iVbnRsk/" />
   <updated>2012-02-01T00:00:00-08:00</updated>
   <id>http://www.williamdurand.fr/2012/02/01/component-driven-development-it-s-like-lego</id>
   <content type="html">&lt;p&gt;Did you ever hear about &lt;strong&gt;Component-Based Development&lt;/strong&gt;? Maybe about &lt;strong&gt;Component Driven Development&lt;/strong&gt;? Both concepts are the same, and if you&amp;#8217;re involved in &lt;em&gt;Symfony2&lt;/em&gt;, &lt;em&gt;Spring&lt;/em&gt;, or something similar, then you do &lt;strong&gt;Component Driven Development&lt;/strong&gt; (&lt;strong&gt;CDD&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;&lt;img src='http://williamdurand.fr/images/posts/lego.jpg' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s all about &lt;strong&gt;separation of concerns&lt;/strong&gt;. You design components with their own logic, each component does &lt;strong&gt;one thing well&lt;/strong&gt;, and &lt;strong&gt;only one thing&lt;/strong&gt;. To separate business logic in self-contained components requires to focus on interactions between components. In other words, you have to think about right interfaces. To help you, UML provides a &lt;strong&gt;component diagram&lt;/strong&gt; which allows you to easily show components, interfaces, and relations.&lt;/p&gt;

&lt;p&gt;In a component diagram, a provided interface is modeled using the lollipop notation, and a required interface is modeled using the socket notation. Small squares represent &lt;em&gt;ports&lt;/em&gt;, which are features with distinct interaction points. So, a &lt;em&gt;port&lt;/em&gt; is an internal component of a classifier.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://www.agilemodeling.com/images/models/componentInterfaces.JPG' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;Most of the time, you won&amp;#8217;t use this kind of diagram because you don&amp;#8217;t like to draw UML diagrams :-). But, as I said previously, you probably know &lt;strong&gt;Component Driven Development&lt;/strong&gt; if you know &lt;em&gt;Symfony2&lt;/em&gt; or &lt;em&gt;Spring&lt;/em&gt;. These two frameworks use the &lt;a href='http://martinfowler.com/bliki/InversionOfControl.html'&gt;&lt;strong&gt;Inversion of Control&lt;/strong&gt;&lt;/a&gt; architectural pattern through the &lt;strong&gt;Dependency Injection&lt;/strong&gt; design pattern (I consider IoC as an architectural pattern because it&amp;#8217;s not a design pattern you can implement).&lt;/p&gt;

&lt;p&gt;A well-known issue when you use &lt;strong&gt;Component Driven Development&lt;/strong&gt; is how to manage dependencies between components, and how to instanciate all your components. Dependency Injection Container to the rescue! By describing component&amp;#8217;s dependencies, and thanks to a container, you&amp;#8217;ll write an highly decoupled application, with components you can reuse.&lt;/p&gt;

&lt;p&gt;The main drawbacks are the time you&amp;#8217;ll spend to think about your architecture, and to know how your components will interact (don&amp;#8217;t forget UML in that case). So, try to find a component before to write your own. In the PHP world, we have magic things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://fabien.potencier.org/article/49/what-is-symfony2'&gt;The Symfony2 components&lt;/a&gt;: a reusable set of standalone PHP components;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://packagist.org/about-composer'&gt;Composer&lt;/a&gt;: the package manager you need;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://packagist.org/'&gt;Packagist&lt;/a&gt;: to discover awesome PHP components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since few months, I work on a project for a French startup, and it&amp;#8217;s my first &lt;strong&gt;Component Driven Development&lt;/strong&gt; experience. I started by listing all my needs (an &lt;em&gt;OAuth&lt;/em&gt; client, a &lt;em&gt;iCalendar&lt;/em&gt; parser, &amp;#8230;). Then, I tried to find one component per point. And, as a glue, I decided to use &lt;strong&gt;Composer&lt;/strong&gt;. After the end of the first sprint, I was a bit confused because I wrote two hundred lines of code (including some test classes), and the project was ever ready to use. I focused on the only important thing: &lt;strong&gt;the aim of the application&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to tools like &lt;em&gt;npm&lt;/em&gt;, &lt;em&gt;gem&lt;/em&gt;, &lt;em&gt;composer&lt;/em&gt;, it&amp;#8217;s like &lt;a href='http://www.lego.com'&gt;Lego&lt;/a&gt;!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/WilliamDurand/~4/4I55iVbnRsk" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://www.williamdurand.fr/2012/02/01/component-driven-development-it-s-like-lego/</feedburner:origLink></entry>
 
 <entry>
   <title>Designing A Software By Naming Things</title>
   <link href="http://feedproxy.google.com/~r/WilliamDurand/~3/2PHK9NVS270/" />
   <updated>2012-01-24T00:00:00-08:00</updated>
   <id>http://www.williamdurand.fr/2012/01/24/designing-a-software-by-naming-things</id>
   <content type="html">&lt;blockquote&gt;
&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and naming things.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Phil Karlton&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Naming things&lt;/strong&gt; is hard, that&amp;#8217;s right, but &lt;strong&gt;naming things&lt;/strong&gt; by their &lt;strong&gt;rights names&lt;/strong&gt; is even harder!&lt;/p&gt;

&lt;p&gt;When you start writing a new application, the first step is often to rely on some &lt;a href='http://en.wikipedia.org/wiki/Unified_Modeling_Language'&gt;UML&lt;/a&gt; diagrams. It allows you to think before to code, what a nice idea!&lt;/p&gt;

&lt;p&gt;Even if use cases or user stories are essential, a &lt;strong&gt;class diagram&lt;/strong&gt; is probably the most useful UML diagram. A first step can be to find packages names (more or less &lt;em&gt;sub-namespaces&lt;/em&gt;), and to connect them. It will give you the main components of your application like the &lt;em&gt;controllers&lt;/em&gt;, the &lt;em&gt;services&lt;/em&gt;, the &lt;em&gt;model&lt;/em&gt;, or the &lt;em&gt;configuration&lt;/em&gt; part for instance. It&amp;#8217;s quite easy to separate concerns at this level. If you use the well-known &lt;em&gt;Model View Controller&lt;/em&gt; design pattern, you almost ever know your packages.&lt;/p&gt;

&lt;p&gt;Once you&amp;#8217;ve defined your packages, you have to find names for your classes. To help you finding the rights names, you can write &lt;strong&gt;interfaces&lt;/strong&gt; first. An interface describes a contract between two entities. This is not related to naming, but if you start by writing interfaces, you start by thinking about interactions between your components. Program to interface is a nice way to design an application, and reduces coupling but it&amp;#8217;s not the purpose of this post.&lt;/p&gt;

&lt;p&gt;My Golden Rule is: &lt;strong&gt;if you&amp;#8217;re not able to find a name for a class, then ask yourself if this class makes sense&lt;/strong&gt;, or if you can decouple things a bit more.&lt;/p&gt;

&lt;p&gt;A wrong name or a non-explicit name often lead to errors. If you&amp;#8217;re not satisfied with your naming, then think again because you probably missed something. Inspire yourself by reading good code, thanks to &lt;a href='http://www.github.com'&gt;GitHub&lt;/a&gt;, it&amp;#8217;s easy to browse awesome code. As a PHP developer, I often use &lt;a href='http://www.github.com/symfony/symfony'&gt;Symfony2&lt;/a&gt; naming in my own projects.&lt;/p&gt;

&lt;p&gt;By following these advices, you&amp;#8217;ll build a software with a &lt;strong&gt;better separation of concerns&lt;/strong&gt;, and each component will be decouple, and will own its own logic, nothing more. That way, you&amp;#8217;ll be able to unit test your application without any effort. And, as you have a good separation of concerns, each unit test can cover a use case.&lt;/p&gt;

&lt;p&gt;This is my last point, always write unit tests that make sense, and think them as use cases. Take a look at the &lt;a href='http://www.github.com/propelorm/Propel2/tree/master/tests/Propel/Tests'&gt;Propel2 test suite&lt;/a&gt;, each test method has a readable name which explains a use case: &lt;code&gt;testIsValidReturnsFalseIfNoUserFound()&lt;/code&gt; is really explicit for instance. Don&amp;#8217;t forget, &lt;strong&gt;the best documentation you can write is tests&lt;/strong&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/WilliamDurand/~4/2PHK9NVS270" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://www.williamdurand.fr/2012/01/24/designing-a-software-by-naming-things/</feedburner:origLink></entry>
 
 <entry>
   <title>My Git Branching Model</title>
   <link href="http://feedproxy.google.com/~r/WilliamDurand/~3/jEThY4LpaQM/" />
   <updated>2012-01-17T00:00:00-08:00</updated>
   <id>http://www.williamdurand.fr/2012/01/17/my-git-branching-model</id>
   <content type="html">&lt;p&gt;We all probably know &lt;a href='http://nvie.com/posts/a-successful-git-branching-model/'&gt;a successful Git branching model&lt;/a&gt; which is a very interesting model for teams who want to use Git. However, this model is a bit too complex for common needs. So here is my lightweight model.&lt;/p&gt;

&lt;p&gt;I use two main branches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;master&lt;/code&gt; : the code in a &lt;em&gt;production-ready&lt;/em&gt; state;&lt;/li&gt;

&lt;li&gt;&lt;code&gt;develop&lt;/code&gt; : the &lt;em&gt;integration branch&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src='http://nvie.com/img/2009/12/bm002.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;I also use &lt;strong&gt;feature branches&lt;/strong&gt;. A feature branch contains a work in progress. Keep in mind that a feature branch should reflect a feature in your backlog. I use a convention for these branches, I always prefix them with &lt;code&gt;feat-&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; git branch
feat-my-feature
* master&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A feature branch has two constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the code must come from the &lt;code&gt;develop&lt;/code&gt; branch;&lt;/li&gt;

&lt;li&gt;the code must be merged in the &lt;code&gt;develop&lt;/code&gt; branch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src='http://nvie.com/img/2009/12/fb.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;To create a feature branch, I use the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; git checkout -b feat-my-feature develop&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To merge a feature branch into &lt;code&gt;develop&lt;/code&gt;, I use the following set of commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Go back to the develop branch
&amp;gt; git checkout develop

# Get last commits
&amp;gt; git pull --ff-only origin develop

# Switch to the feature branch
&amp;gt; git checkout feat-my-feature

# Time to rebase
&amp;gt; git rebase develop

# Then, switch to the develop branch in order to merge the feature branch
&amp;gt; git checkout develop

&amp;gt; git merge --no-ff feat-my-feature

# Push
&amp;gt; git push origin develop

# Finally, delete your branch
&amp;gt; git branch -d feat-my-feature&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I always merge a feature branch into &lt;code&gt;develop&lt;/code&gt; using &lt;code&gt;--no-ff&lt;/code&gt; to keep a clean log:&lt;/p&gt;

&lt;p&gt;&lt;img src='http://nvie.com/img/2010/01/merge-without-ff.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;--no--ff&lt;/code&gt; option allows to keep track of a feature branch name which is quite useful. The following &lt;code&gt;git log&lt;/code&gt; output shows you a feature branch merged with this option:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;commit 481771556824c4ae2e6da73ef14d6ce757fb5870
Merge: 6abdd70 8cfe5a7
Author: William DURAND &amp;lt;william.durand1@gmail.com&amp;gt;
Date:   Tue Jan 17 11:31:56 2012 +0100

Merge branch &amp;#39;feat-my-feature&amp;#39; into develop

commit 8cfe5a7da159663cc09a850bee49a59ce046c67e
Author: William DURAND &amp;lt;william.durand1@gmail.com&amp;gt;
Date:   Tue Jan 17 11:31:19 2012 +0100

Added a new feature

commit 6abdd707aace50ee5aad72a3c6fcff2f36cdea7f
Author: William DURAND &amp;lt;william.durand1@gmail.com&amp;gt;
Date:   Sun May 15 14:07:19 2011 +0200

Initial commit&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Without the &lt;code&gt;--no-ff&lt;/code&gt; option, you&amp;#8217;ll get the following output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;commit 0d5805d52e55e4941ce23585a4cd559e5e643207
Author: William DURAND &amp;lt;william.durand1@gmail.com&amp;gt;
Date:   Tue Jan 17 11:35:43 2012 +0100

Added yet another feature

commit 6abdd707aace50ee5aad72a3c6fcff2f36cdea7f
Author: William DURAND &amp;lt;william.durand1@gmail.com&amp;gt;
Date:   Sun May 15 14:07:19 2011 +0200

Initial commit&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In a team, you will probably have more than one feature branch, and you could have a depencency between two branches (this should be avoided). In this case, I use another branch in which I merge two or more feature branches.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; git checkout -b feat-my-feature-with-another-feature develop&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, I can merge the two feature branches, and solves conflicts in it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; git merge feat-my-feature

&amp;gt; git merge feat-another-feature&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I don&amp;#8217;t use any other branches. The last part of the model is to merge &lt;code&gt;develop&lt;/code&gt; into &lt;code&gt;master&lt;/code&gt;. To avoid conflicts, there should be only one person who owns this responsability: the &lt;strong&gt;release manager&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I experimented this model with different teams in terms of number of people and skills, and I never had more needs. I know some people use &lt;strong&gt;releases&lt;/strong&gt; but it can be handled in another way.&lt;/p&gt;

&lt;p&gt;All credits go to Vincent Driessen and his &lt;a href='http://nvie.com/posts/a-successful-git-branching-model/'&gt;Git model&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/WilliamDurand/~4/jEThY4LpaQM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://www.williamdurand.fr/2012/01/17/my-git-branching-model/</feedburner:origLink></entry>
 
 <entry>
   <title>Services Status Dashboard</title>
   <link href="http://feedproxy.google.com/~r/WilliamDurand/~3/CExIva-Uk94/" />
   <updated>2012-01-16T00:00:00-08:00</updated>
   <id>http://www.williamdurand.fr/2012/01/16/services-status-dashboard</id>
   <content type="html">&lt;p&gt;Today, I was looking for an Open Source alternative to &lt;a href='http://www.pingdom.com/a1/'&gt;Pingdom&lt;/a&gt; as I needed something free, customizable, and lightweight. I love the &lt;a href='http://status.github.com'&gt;GitHub&amp;#8217;s Status Panel&lt;/a&gt;, unfortunately they didn&amp;#8217;t open source it.&lt;/p&gt;

&lt;p&gt;Basically, this kind of application is simple. You just need a crawler, and few rules to know whether an application is alive or not. Additionally, you may want to store results in order to make graphs or to calculate uptime average, and so on. Before to write this kind of application myself, I tried to search existing projects on GitHub.&lt;/p&gt;

&lt;p&gt;Good news! I found a really nice project: &lt;a href='https://github.com/obazoud/statusdashboard'&gt;Status Dashboard&lt;/a&gt; created by Olivier Bazoud. This project is easy to configure, you can use provided plugins (Twitter, IRC bot, History, &amp;#8230;) or add your owns, and you can monitor various services (not only HTTP). If you don&amp;#8217;t want to use the beautiful interface, then you&amp;#8217;ll find a REST API.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/posts/statusdashboard.png' alt='' /&gt;&lt;/p&gt;

&lt;h3 id='installation'&gt;Installation&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;npm install&lt;/code&gt; to setup the project and its dependencies, then add your own configuration in &lt;code&gt;settings.js&lt;/code&gt;. Mine is:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='c1'&gt;// ...&lt;/span&gt;
&lt;span class='nx'&gt;settings&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;william&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;services&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;[{&lt;/span&gt;
    &lt;span class='nx'&gt;name&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;williamdurand.fr&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;label&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;William DURAND (blog)&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;check&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;host&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;williamdurand.fr&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;port&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;80&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;path&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;headers&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;Host&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;williamdurand.fr&amp;#39;&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='p'&gt;}],&lt;/span&gt;
  &lt;span class='nx'&gt;plugins&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;history&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;enable&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;host&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;127.0.0.1&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;port&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;6379&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;namespace&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;statusdashboard&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='p'&gt;},&lt;/span&gt;
    &lt;span class='nx'&gt;client&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then, start the server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;node server.js&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Check the server is running by browsing &lt;em&gt;http://127.0.0.1:8080/&lt;/em&gt; or by querying the API:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; curl http://127.0.0.1:8080/api/services
{&amp;quot;lastupdate&amp;quot;:&amp;quot;Mon, 16 Jan 2012 13:29:11 GMT&amp;quot;,&amp;quot;services&amp;quot;:[{&amp;quot;name&amp;quot;:&amp;quot;williamdurand.fr&amp;quot;,&amp;quot;label&amp;quot;:&amp;quot;William DURAND (blog)&amp;quot;,&amp;quot;status&amp;quot;:&amp;quot;up&amp;quot;,&amp;quot;statusCode&amp;quot;:200,&amp;quot;message&amp;quot;:&amp;quot;&amp;quot;}],&amp;quot;summarize&amp;quot;:{&amp;quot;lastupdate&amp;quot;:&amp;quot;Mon, 16 Jan 2012 13:29:11 GMT&amp;quot;,&amp;quot;up&amp;quot;:1,&amp;quot;critical&amp;quot;:0,&amp;quot;down&amp;quot;:0,&amp;quot;unknown&amp;quot;:0}}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The project is available at: &lt;a href='https://github.com/obazoud/statusdashboard'&gt;https://github.com/obazoud/statusdashboard&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/WilliamDurand/~4/CExIva-Uk94" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://www.williamdurand.fr/2012/01/16/services-status-dashboard/</feedburner:origLink></entry>
 
 <entry>
   <title>Did I Tell You Open Source Was Awesome?</title>
   <link href="http://feedproxy.google.com/~r/WilliamDurand/~3/AOUmz1kYkLo/" />
   <updated>2012-01-16T00:00:00-08:00</updated>
   <id>http://www.williamdurand.fr/2012/01/16/did-i-tell-you-open-source-was-awesome</id>
   <content type="html">&lt;p&gt;Few months ago, my father gave me a &lt;a href='http://www.karotz.com/home'&gt;Karotz&lt;/a&gt; (the new Nabaztag) for my birthday. In the same time, I started to learn how to write a &lt;a href='http://jenkins-ci.org/'&gt;Jenkins&lt;/a&gt; plugin, and I knew this kind of rabbit could be programmed. That&amp;#8217;s why I decided to write a &lt;a href='https://github.com/willdurand/Karotz-Plugin'&gt;Karotz-Plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As an Open Source Software enthusiast, I published my code on GitHub right at the beginning. The plugin was in a work in progress state, but quite usable. Unfortunately, I was unable to improve it for few weeks.&lt;/p&gt;

&lt;p&gt;When I got some free time to work on it, I saw my repository was forked. Surprise! Someone improved my work, and published it as an &lt;a href='https://wiki.jenkins-ci.org/display/JENKINS/Karotz+Plugin'&gt;official Jenkins Plugin&lt;/a&gt;. Wonderful!&lt;/p&gt;

&lt;p&gt;So, I pulled the repository, and learnt a lot from the developer who worked on the plugin. Isn&amp;#8217;t it awesome? First, my code has been reused. Second, I learnt new things. Oh! And I got an awesome plugin for Jenkins and my Karotz!&lt;/p&gt;

&lt;p&gt;To sum up, it&amp;#8217;s a often really good idea to &lt;a href='http://tom.preston-werner.com/2011/11/22/open-source-everything.html'&gt;open source everything&lt;/a&gt;, even if it&amp;#8217;s a draft, a work in progress, or just an idea. Someone could find this idea awesome, and could work on it. And thanks to &lt;a href='http://www.github.com'&gt;GitHub&lt;/a&gt;, to open source something is really really easy :)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/WilliamDurand/~4/AOUmz1kYkLo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://www.williamdurand.fr/2012/01/16/did-i-tell-you-open-source-was-awesome/</feedburner:origLink></entry>
 
 <entry>
   <title>Hello, World!</title>
   <link href="http://feedproxy.google.com/~r/WilliamDurand/~3/0f84Y1w2gYc/" />
   <updated>2012-01-15T00:00:00-08:00</updated>
   <id>http://www.williamdurand.fr/2012/01/15/hello-world</id>
   <content type="html">&lt;p&gt;Hi folks!&lt;/p&gt;

&lt;p&gt;Few months ago, I decided to lock &lt;a href='http://www.willdurand.fr'&gt;my plain old blog&lt;/a&gt; in French. To own a blog is really important but I was bored to write in French, and I had no free time to answer comments, to write new entries, and so on.&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s why I&amp;#8217;m starting this new blog, in English (as well-written as possible) powered by &lt;a href='https://github.com/mojombo/jekyll'&gt;Jekyll&lt;/a&gt;, &lt;a href='http://html5boilerplate.com/'&gt;HTML5 Boilerplate&lt;/a&gt;, and hosted by &lt;a href='http://www.github.com'&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You&amp;#8217;ll get the code by browsing the following repository: &lt;a href='https://github.com/willdurand/willdurand.github.com'&gt;willdurand/willdurand.github.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;William&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/WilliamDurand/~4/0f84Y1w2gYc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://www.williamdurand.fr/2012/01/15/hello-world/</feedburner:origLink></entry>
 

</feed>

