<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[James Gregory]]></title>
  <link href="http://www.jagregory.com/atom.xml" rel="self"/>
  <link href="http://www.jagregory.com/"/>
  <updated>2012-07-05T00:32:55+10:00</updated>
  <id>http://www.jagregory.com/</id>
  <author>
    <name><![CDATA[James Gregory]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Rails production 500 error page showing in dev]]></title>
    <link href="http://www.jagregory.com/writings/rails-500-error-showing-in-dev/"/>
    <updated>2012-07-05T00:00:00+10:00</updated>
    <id>http://www.jagregory.com/writings/rails-500-error-showing-in-dev</id>
    <content type="html"><![CDATA[<blockquote><p>We&#8217;re sorry, but something went wrong!</p></blockquote>

<p>I&#8217;ve been seeing some strange behaviour on the development environment for <a href="http://www.getonthegame.com.au">On the Game</a> recently. I&#8217;ve just spent an hour combing through every line of code that varies from a standard Rails app, and I&#8217;ve finally found the issue. I&#8217;m putting it here for posterity.</p>

<p>Regardless of my configuration, Rails was always displaying the production page for 500 errors (<code>public/500.html</code>) even in development mode.</p>

<p>I poked around for a while and eventually found it to be this:</p>

<p>I&#8217;d redefined <code>Enumerable#sum</code> somewhere (don&#8217;t ask!), and my implementation didn&#8217;t handle arrays of strings. That&#8217;s it, that&#8217;s why the detailed error page wasn&#8217;t being shown in development.</p>

<p>Ends up, <code>Enumerable#sum</code> is used by the development error page, and when something on that error page itself raises an error Rails will just fall back and show the 500.html and not log anything.</p>

<p>Moral of the story: If you&#8217;re seeing this behaviour, check you haven&#8217;t (badly) monkey patched something that the error page is using.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Learning. It ain't hard.]]></title>
    <link href="http://www.jagregory.com/writings/learning-it-aint-hard"/>
    <updated>2011-07-06T00:00:00+10:00</updated>
    <id>http://www.jagregory.com/writings/learning-it-aint-hard</id>
    <content type="html"><![CDATA[<p>&#8220;I don&#8217;t have enough free time to learn a new language!&#8221;, or tool, or framework, etc. I hear this often. I appreciate we all handle things differently, but here&#8217;s my take on it.</p>

<p>I remember years ago, some friends and I were talking about money and our savings accounts. They were flabbergasted at how I, a 19 year old at the time, were able to have nearly £10,000 saved (sadly which I&#8217;ve since spent!). I explained that it&#8217;s easy to save money if you do it slowly and consistently. £50 a week over the course of three years adds up. Obvious, right?</p>

<p>You don&#8217;t sit down and decide &#8220;I&#8217;m going to save £10,000&#8221; and then promptly spend one month working yourself to death to put away the whole amount in one go. It&#8217;d be nice to have the option to do that occasionally, but that&#8217;s not how most of us work. The same applies to learning.</p>

<p>You don&#8217;t need to read a 300 page book to learn something. Read a blog post (or an article, mailing list thread, commit discussion). One. Pick a subject and read a single article on it. Do this once a week, every week. That&#8217;s it, that&#8217;s my secret to learning.</p>

<p>Knowledge isn&#8217;t a substitute for experience, but it&#8217;ll certainly get you a lot further down the road, faster, than you would get without it.</p>

<p>Take Ruby as the typical example. Ruby on Rails has been around for 6 years now (and Ruby for nearly 15, but not visibly), if you&#8217;d have read one article on Ruby a week, you&#8217;d have read 312 by now. Three hundred and twelve. Combine that with the occasional Sunday afternoon playing around and I&#8217;m confident you&#8217;d be pretty proficient by now.</p>

<ul>
<li>Javascript is around 15 years old.</li>
<li>Haskell, 20 years.</li>
<li>Erlang, 25 years.</li>
<li>Python, 20 years.</li>
<li>Clojure, 4 years. Scheme? 36 years.</li>
</ul>

<p>Of course, we&#8217;ve not all been trying to learn those languages for as long as they&#8217;ve existed. Consider this though, in one year you could be proficient in a new language if you commit to just 15 minutes a week, or you could be in exactly the same place you are now still unable to find time to learn anything.</p>

<p>How do you eat an elephant? <em>One bite at a time.</em></p>

<h2 id="addendum_but_everything_moves_so_fast">Addendum: but everything moves so fast!</h2>

<p>No, it doesn&#8217;t. It just feels like that from the inside.</p>

<p>Learn something fundamental and your knowledge will transcend trends. Learning a new language is a great way to do that whilst also feeling cool and trendy. Ruby or Python will help you understand dynamic languages, Scala will make you appreciate how powerful and unobtrusive static languages can be, and Clojure will introduce the code-as-data mindset. All those things will be useful beyond the scope of the language you&#8217;re learning.</p>

<p><em>Stealth edit: Fixed my amazing saving ability.</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rhino Licensing]]></title>
    <link href="http://www.jagregory.com/writings/rhino-licensing/"/>
    <updated>2011-01-11T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/rhino-licensing</id>
    <content type="html"><![CDATA[<blockquote><p>As one of the last things on my to-do list for <a href="http://inca-app.com">Inca</a>, licensing has been delayed and delayed; finally, with me making the announcement on Twitter the other day I felt I should probably get it sorted. I was going to write a nice long post about my thoughts on anti-piracy measures, but the <a href="http://blogs.balsamiq.com/product//2008/10/19/my-views-on-software-piracy/">Balsamiq team have already done it nicely</a>.</p>

<p>Instead, here&#8217;s a guide to using <a href="https://github.com/ayende/rhino-licensing">Rhino Licensing</a>. Your mileage may vary.</p></blockquote>

<p><a href="https://github.com/ayende/rhino-licensing">Rhino Licensing</a> is an open-source licensing framework by <a href="http://ayende.com">Ayende Rahien</a>, and it grew out of his frustration with other license providers while creating <a href="http://nhprof.com/">NHibernate Profiler</a>.</p></p>

<p>Rhino Licensing uses asymmetric encryption&#8211;also known as <a href="http://en.wikipedia.org/wiki/Public-key_cryptography">public-key cryptography</a>&#8211;specifically the <a href="http://en.wikipedia.org/wiki/RSA">RSA algorithm</a>. In cryptography, asymmetric means there are two parts to each key, one public and one private. You encrypt a value using the one key, and it can only be decrypted using the other key. In the case of license key generation, we store our private key on the server (and never tell anyone it!), and distribute the public key with our application. When the user receives a license key, the application is able to verify that it came from us by using the public key. If someone tries to use a license key they&#8217;ve generated themselves, it wouldn&#8217;t work unless they had our exact private key.</p>

<blockquote><p>Other systems that use asymmetric encryption include <abbr title="Secure Shell">SSH</abbr>, <abbr title="Secure Sockets Layer">SSL</abbr>, <abbr title="Pretty Good Privacy">PGP</abbr>, and among others, Git uses asymmetric encryption for its security due to it using SSH.</p></blockquote>

<p>The format of the license that Rhino Licensing generates is an XML document, plain and simple. By default, it includes the user&#8217;s name, an expiration date, the type of license (trial, standard, floating, etc&#8230;), and most importantly the cryptographic signature. Below is an example Rhino Licensing generated license.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span>
</span><span class='line'><span class="nt">&lt;license</span> <span class="na">id=</span><span class="s">&quot;ae4c05b5-c188-47f8-852f-b4e5375621f7&quot;</span>
</span><span class='line'>    <span class="na">expiration=</span><span class="s">&quot;2011-01-01T00:00:00.0000000&quot;</span> <span class="na">type=</span><span class="s">&quot;Standard&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;name&gt;</span>Bilbo<span class="nt">&lt;/name&gt;</span>
</span><span class='line'>  <span class="nt">&lt;Signature</span> <span class="na">xmlns=</span><span class="s">&quot;http://www.w3.org/2000/09/xmldsig#&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;SignedInfo&gt;</span>
</span><span class='line'>      <span class="nt">&lt;CanonicalizationMethod</span> <span class="na">Algorithm=</span><span class="s">&quot;http://www.w3.org/TR/2001/REC-xml-c14n-20010315&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>      <span class="nt">&lt;SignatureMethod</span> <span class="na">Algorithm=</span><span class="s">&quot;http://www.w3.org/2000/09/xmldsig#rsa-sha1&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>
</span><span class='line'>      <span class="nt">&lt;Reference</span> <span class="na">URI=</span><span class="s">&quot;&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nt">&lt;Transforms&gt;</span>
</span><span class='line'>          <span class="nt">&lt;Transform</span> <span class="na">Algorithm=</span><span class="s">&quot;http://www.w3.org/2000/09/xmldsig#enveloped-signature&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>        <span class="nt">&lt;/Transforms&gt;</span>
</span><span class='line'>        <span class="nt">&lt;DigestMethod</span> <span class="na">Algorithm=</span><span class="s">&quot;http://www.w3.org/2000/09/xmldsig#sha1&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>        <span class="nt">&lt;DigestValue&gt;</span>sKDT7gzgedzmh1AMxxLbfcF1Hsw=<span class="nt">&lt;/DigestValue&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/Reference&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/SignedInfo&gt;</span>
</span><span class='line'>    <span class="nt">&lt;SignatureValue&gt;</span>
</span><span class='line'>        SfkvCGv1+EdLTvaROv27ymDumS0y02fPANTVhr0Yxd/
</span><span class='line'>        AxxVH0q0BQ6w8Ou5L7gyLYLvnSckgjhrGnGpiifdvbg==
</span><span class='line'>    <span class="nt">&lt;/SignatureValue&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/Signature&gt;</span>
</span><span class='line'><span class="nt">&lt;/license&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<blockquote><h2>What&#8217;s a signature?</h2>

<p>A cryptographic signature is a string of bytes used to aid in verification of the source of a document. In most cases&#8211;and in the case of Rhino Licensing&#8211;the signature is generated by hashing the content of the file using SHA1 (or another suitable hashing algorithm), and encrypting that hash using the private key. The resulting string of bytes is the signature.</p>

<p>When the client receives a file with a signature, it creates a hash of the file (sans-signature) and compares that hash to the decrypted value of the signature. Baring in mind that the signature is an encrypted hash of the file, if either of the public or private keys were invalid or the file had been tampered with, then the decrypted string would not match the hash of the file. When the client generated hash and the decrypted signature match, you can be confident the sender of the message is who you think it is.</p></blockquote>

<p>The great part about using the hash of the document as the signature is that if the user tampers with the license&#8211;such as changing the expiration date or the licensee name&#8211;the signature will no longer match the hash the client generates, and BAM, instant invalid license.</p>

<blockquote><p>One particular aspect I like with this approach is that the licensee name is clearly visible in the license. This simple act can be quite dissuasive when it comes to piracy; after all, who would want their name visible on all the torrent websites out there?</p></blockquote>

<p>Enough with the waffle, let&#8217;s start using Rhino Licensing.</p>

<h2>Create your key</h2>

<p>The first thing we need to do is generate a public/private key pair for us to use in our license generation. Rhino Licensing uses the RSACryptoServiceProvider for it&#8217;s keys, so we can use that ourselves to generate our keys. One of the simplest ways to do that is to knock up a really quick console application.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">class</span> <span class="nc">Program</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="n">var</span> <span class="n">rsa</span> <span class="p">=</span> <span class="k">new</span> <span class="n">RSACryptoServiceProvider</span><span class="p">(</span><span class="m">1024</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">File</span><span class="p">.</span><span class="n">WriteAllText</span><span class="p">(</span><span class="s">&quot;publicKey.xml&quot;</span><span class="p">,</span> <span class="n">rsa</span><span class="p">.</span><span class="n">ToXmlString</span><span class="p">(</span><span class="k">false</span><span class="p">));</span>
</span><span class='line'>    <span class="n">File</span><span class="p">.</span><span class="n">WriteAllText</span><span class="p">(</span><span class="s">&quot;privateKey.xml&quot;</span><span class="p">,</span> <span class="n">rsa</span><span class="p">.</span><span class="n">ToXmlString</span><span class="p">(</span><span class="k">true</span><span class="p">));</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;Done&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">Console</span><span class="p">.</span><span class="n">ReadKey</span><span class="p">();</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>That program will generate a new key for you and write out the public and private parts to two separate XML files (publicKey.xml and privateKey.xml). Keep these two files handy!</p>

<blockquote><p>You will probably want to change the <code>1024</code> value in the <code>RSACryptoServiceProvider</code> constructor to something larger. This is the size of the key that will be generated. The larger the better really, but larger numbers require longer to generate.</p></blockquote>

<h2>Update your application</h2>

<p>Now we&#8217;ll update your application to complain if it doesn&#8217;t have a license. In your entry-point for your application you need to assert the license. Before we do that, make sure you&#8217;ve got your public key handy from the previous step. Rhino Licensing needs the <em>content</em> of this file, so you can either embed it directly into a constant or as a resource. Secondly, it needs to know where to look for a license that the user will have been given.</p>

<p>Assuming a really simple app, here&#8217;s a Program.cs with Rhino Licensing:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">class</span> <span class="nc">Program</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">()</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="n">var</span> <span class="n">publicKey</span> <span class="p">=</span> <span class="n">File</span><span class="p">.</span><span class="n">ReadAllText</span><span class="p">(</span><span class="s">&quot;publicKey.xml&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">new</span> <span class="nf">LicenseValidator</span><span class="p">(</span><span class="n">publicKey</span><span class="p">,</span> <span class="s">&quot;license.xml&quot;</span><span class="p">)</span>
</span><span class='line'>      <span class="p">.</span><span class="n">AssertValidLicense</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;Hello&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">Console</span><span class="p">.</span><span class="n">ReadKey</span><span class="p">();</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>If the license.xml file doesn&#8217;t exist, or if it&#8217;s invalid, Rhino Licensing will throw an exception. Of course, as we haven&#8217;t generated a license yet we&#8217;ll get an exception. That&#8217;s the client done though, so we can move on to our final step now. Once we complete that step, you will be able to just drop a license.xml into the same directory as your application and everything will work as expected.</p>

<h2>Create the license generator</h2>

<p>We need something to actually generate a license for your users. If you were being all fancy you could do this as a web-service that gets integrated with your payment provider; however, for simplicity&#8217;s sake we&#8217;ll just create another console application that spits out a license.</p>

<p>Rhino Licensing has a few prerequisites for a license: A name, an id of the license, an expiration date, and a license type. You can also supply a dictionary of custom values, but we wont be using that in this example.</p>

<p>For a really simple license generator all you need is the above for each license, and the private key. We&#8217;ll wrap that up in a simple console app which&#8217;ll prompt for the required info:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">class</span> <span class="nc">Program</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="n">var</span> <span class="n">privateKey</span> <span class="p">=</span> <span class="n">File</span><span class="p">.</span><span class="n">ReadAllText</span><span class="p">(</span><span class="s">&quot;privateKey.xml&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">var</span> <span class="n">id</span> <span class="p">=</span> <span class="n">Guid</span><span class="p">.</span><span class="n">NewGuid</span><span class="p">();</span>
</span><span class='line'>    <span class="n">var</span> <span class="n">generator</span> <span class="p">=</span> <span class="k">new</span> <span class="n">LicenseGenerator</span><span class="p">(</span><span class="n">private_key</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">&quot;Name: &quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">var</span> <span class="n">name</span> <span class="p">=</span> <span class="n">Console</span><span class="p">.</span><span class="n">ReadLine</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">&quot;Date: &quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">var</span> <span class="n">expirationDate</span> <span class="p">=</span> <span class="n">DateTime</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="n">Console</span><span class="p">.</span><span class="n">ReadLine</span><span class="p">());</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">&quot;Type: &quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">LicenseType</span> <span class="n">licenseType</span> <span class="p">=</span> <span class="p">(</span><span class="n">LicenseType</span><span class="p">)</span><span class="n">Enum</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">LicenseType</span><span class="p">),</span> <span class="n">Console</span><span class="p">.</span><span class="n">ReadLine</span><span class="p">());</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// generate the license</span>
</span><span class='line'>    <span class="n">var</span> <span class="n">license</span> <span class="p">=</span> <span class="n">generator</span><span class="p">.</span><span class="n">Generate</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">id</span><span class="p">,</span> <span class="n">expirationDate</span><span class="p">,</span> <span class="n">licenseType</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">();</span>
</span><span class='line'>    <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">license</span><span class="p">);</span>
</span><span class='line'>    <span class="n">Console</span><span class="p">.</span><span class="n">ReadKey</span><span class="p">();</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>That&#8217;s it, you&#8217;ve got a license generator. Remember, this will exist behind your firewall, the users will (and must) never see your private key.</p>

<p>If you take the output of this application and save it in a license.xml file in your client, your application should stop throwing license exceptions and run normally! You&#8217;ve officially just licensed your app.</p>

<h2>What have we just done?</h2>

<ul>
<li>Created a private key generator, purely for convenience than anything else. We should only need to run this once before we start generating our keys. You could run it once per major release to ensure your 1.0 licenses are never compatible with 2.0.</li>
<li>Updated our client application to validate the presence and validity of a license (and to explode if there isn&#8217;t one).</li>
<li>Created a &#8220;server&#8221; to generate licenses for us. This is very primitive but could easily be adapted to a web server. You might want to look at the Rhino Licensing <a href="https://github.com/ayende/rhino-licensing/blob/master/Rhino.Licensing/LicensingService.cs">LicensingService</a> before you continue.</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[NDC 2010]]></title>
    <link href="http://www.jagregory.com/writings/ndc-2010/"/>
    <updated>2010-06-22T00:00:00+10:00</updated>
    <id>http://www.jagregory.com/writings/ndc-2010</id>
    <content type="html"><![CDATA[<a href="http://www.ndc2010.no">NDC 2010</a> was a huge success, if you ask me. This was largely down to the NDC team, who deserve all the praise they&#8217;re getting (and much more). Unlike conferences I&#8217;ve been to in the past, NDC was truely by the people, for the people. <a href="http://blog.scottbellware.com">Scott Bellware</a> put it much better than I could, with his <a href="http://blog.scottbellware.com/2010/06/praise-for-norwegian-developers.html">praise for Norwegian Developers</a> (and Kjersti Sandberg). Herself and the rest of the team were there because they wanted to be, not because they had to. The whole attitude surrounding this conference was one of learning, not plugging products or motives.

I could go into great detail about the individual aspects of the conference, but it&#8217;s much easier to say that there&#8217;s nothing I&#8217;d change.

If there&#8217;s one conference you should go to next year, make it NDC 2011.

<h2>My part in all this&#8230;</h2>

I presented on two topics at NDC; the first was an introduction to <a href="http://fluentnhibernate.org">Fluent NHibernate</a>, and the second an introduction and demo of <a href="http://git-scm.com">Git</a>. Fluent NHibernate was on the Thursday, and Git the Friday. It was a great experience speaking at an event of this size, and the number of people who seemed genuinely interested in what I had to say (by either turning up to my talks, or approaching me afterwards) was quite humbling. If you&#8217;re interested in seeing what I presented, the talks will be on the NDC website before too long.

<blockquote>The videos are becoming available at <a href="http://streaming.ndc2010.no">streaming.ndc2010.no</a>, but they&#8217;re suffering from bandwidth issues. If you do want to watch the videos, please stream them until the issues are resolved.</blockquote>

Due to me speaking, and also being woefully unprepared, I didn&#8217;t get to see as many talks as I would&#8217;ve liked &mdash; regardless of how well rehearsed and prepared my talks are, it seems I always end up rewriting them an hour before I go on &mdash; I did end up catching Lisa Crispin, Steve Strong, Eric Evans, Greg Young, Jon Skeet, Roy Osherove, Michael Feathers, Sebastian Lambla, and Mark Nijhof. I recommend you catch their talks online when they&#8217;re published. The quality of the talks at NDC have been significantly higher than I&#8217;ve seen elsewhere, and (more importantly) the technical level seems to be higher too; there was very few basic talks (a few introductions, mine included, but no pandering), but the majority were pretty in-depth. This is quite a contrast to the all-too-often &#8220;Microsoft technology of the week&#8221; presentations you can get at conferences.

Of course, a big part of any conference is what happens between (and after) the talks. Meeting other developers is a big part of why I go to these things, after all I don&#8217;t get out much normally. The socialising aspect of NDC was excellent, good drinks and food was had by all (I have a good idea they did anyway, at least one place we ate refused to serve us as a group anything other than the same meal for everyone!). I can&#8217;t possibly list everyone who I met while I was out there, but it was really good to meet up with some people who I&#8217;ve known on Twitter for a long time; specifically Hadi Hariri, Steve Strong, Greg Young, Ben Hall, Seb Lambla, Mark Nijhof, and Rob Conery are ones that stand out to me right now.

NDC 2011 will be next year, and it&#8217;s looking like it&#8217;ll be in May this time. If there&#8217;s anyone that&#8217;s on the fence about going, I would whole heartedly recommend you do. Even more so, I&#8217;d recommend you submit a talk of your own. It&#8217;s a great way to test yourself, if nothing else. I&#8217;ll definitely be going next year; hopefully I&#8217;ll speak again, but if not I&#8217;ll still be there. Hope to see you there!
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Speaking engagements in 2010]]></title>
    <link href="http://www.jagregory.com/writings/speaking-engagements-2010/"/>
    <updated>2010-03-31T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/speaking-engagements-2010</id>
    <content type="html"><![CDATA[In an attempt to get out of my shell more this year, I&#8217;ve taken up speaking (at conferences, not just in general). First came my <a href="http://jagregory.com/writings/git-e-van-recording/">Git E-VAN</a>, then came <a href="http://fiesta.lostechies.com/">Pablo&#8217;s Fiesta</a>, so what else have I got lined up this year?

<strong>24<sup>th</sup> April</strong>: <a href="http://codingday.org/">Irish Open Spaces Coding Day II</a> in Dublin, where I&#8217;ll be speaking about <a href="http://fluentnhibernate.org">Fluent NHibernate</a>.

<strong>16<sup>th</sup>-18<sup>th</sup> June</strong>: <a href="http://ndc2010.no" title="Norwegian Developers Conference 2010">NDC 2010</a> in Oslo, speaking about <a href="http://fluentnhibernate.org">Fluent NHibernate</a> and DVCS with Git.

The abstracts for my talks can be found below. If you&#8217;re interested in hearing me speak, or know of any opportunities that you think I might be interested in, please drop me an email (<a href="mailto:james@jagregory.com">james@jagregory.com</a>). You can see my availability on my <a href="http://www.google.com/calendar/embed?src=mtbk7g2u13e2j7s1u8p0flitho@group.calendar.google.com&ctz=Europe/London&gsessionid=GBDJzqgaRWqAze87fNda9Q">speaking calendar</a>.

<h3>Fluent NHibernate</h3>

An introduction and overview to object⁄relational mapping using Fluent NHibernate. See how Fluent NHibernate can help you map your domain with the least amount of effort, how you can remain flexible with your database, and how to drive your design through convention–over–configuration; all without writing a single line of XML.

The talk is an introduction to Fluent NHibernate for those that aren&#8217;t familiar with it, and assumes some NHibernate experience and is for .Net developers primarily. The goal is to show people how low–impact NHibernate can be with Fluent NHibernate, and how it can actually speed up development in rapid–change environments.

I&#8217;ll cover an overview of what Fluent NHibernate is, the various parts of it (the fluent interface, the conventions, and the auto–mappings, and the configuration aspect), then expand on how these features can be utilised to improve your NHibernate experience and simplify your development process.

<h3>Introduction to Git</h3>

An introduction to distributed version control using Git, and how your VCS should work with you and not against you. How DVCS can completely alter your development process, streamline it, and help you produce better software, faster. Covering how local repositories speed up your development, multiple authoritative sources, distributed teams, multiple workflows, and some of the more distinct features of Git. With experiences from an OSS team on how the migration from SVN to Git has helped the project and changed how the team works (Fluent NHibernate).
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git E-VAN recording]]></title>
    <link href="http://www.jagregory.com/writings/git-e-van-recording/"/>
    <updated>2010-02-17T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/git-e-van-recording</id>
    <content type="html"><![CDATA[<p>Last monday (8th of Feb) I did an <a href="http://jagregory.com/writings/git-e-van/">E-VAN on Git</a>; an introductory talk on Git and DVCS, covering pretty much everything you need to know for day-to-day Git life. I think it went down well, certainly didn&#8217;t <em>hear</em> anyone complaining.</p>

<p>The talk was recorded, so if you haven&#8217;t already seen it then you can do so at your own leisure.</p>

<p>The video is up on the <a href="http://vimeo.com/user1286822">E-VAN&#8217;s Vimeo account</a>, specifically <a href="http://vimeo.com/9324683" title="Git E-VAN recording">here</a>.</p>

<object width="600" height="450"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9324683&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9324683&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="600" height="450"></embed></object>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git E-VAN]]></title>
    <link href="http://www.jagregory.com/writings/git-e-van/"/>
    <updated>2010-02-08T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/git-e-van</id>
    <content type="html"><![CDATA[<p>Just a reminder that tonight I&#8217;ll be doing an <a href="http://europevan.blogspot.com/2010/01/next-european-van-on-08-february-2010.html">E-VAN on Git</a> tonight at 7pm GMT.</p>

<p>It&#8217;s going to be a pretty basic talk on what Git is (and indirectly what DVCS is), and a demo on how to use most of the features you&#8217;ll need daily. There might be some advanced talk at the end, depending on how well I time things.</p>

<p>If you&#8217;ve already used Git (successfully), then this talk won&#8217;t really be for you; unless you just want to listen to me ramble for an hour and an half.</p>

<p>Looking forward to &#8220;seeing&#8221; you there. Now, I best finish reading that &#8220;Getting started with Git&#8221; book I&#8217;ve had lying around for months.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git: Remotes, contributions, and the letter N]]></title>
    <link href="http://www.jagregory.com/writings/git-remotes-contributions-and-the-letter-n/"/>
    <updated>2010-02-07T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/git-remotes-contributions-and-the-letter-n</id>
    <content type="html"><![CDATA[<p>Here&#8217;s a few ways to think about Git and it&#8217;s distributed nature.</p>

<ul>
<li>You deal with multiples of repositories, not a single central repository</li>
<li>Updates come from a remote repository, and changes are pushed to a remote; none of these repositories have to be the same</li>
<li><em>Origin</em> is the canonical name for the repository you cloned from</li>
<li><em>Upstream</em> is the canonical name for the original project repository you forked from</li>
</ul>




<h2>General pushing and pulling</h2>


<p><img src="http://www.jagregory.com/images/remote-1.png" alt="Figure 1" /></p>

<p>Pushing your changes to a remote: <code>git push remote_name</code></p>

<p><img src="http://www.jagregory.com/images/remote-2.png" alt="Figure 2" /></p>

<p>Pulling changes from a remote: <code>git pull remote_name</code></p>

<p>Or if you want to rebase:</p>

<pre>git fetch remote_name
git rebase remote_name/branch</pre>




<blockquote>You can change your <code>branch.autosetuprebase</code> to <code>always</code>, to make this the default <code>git pull</code> behaviour.</blockquote>


<p>That&#8217;s all there is to moving commits around in Git repositories. Any other operations you perform are all combinations of the above.</p>

<h2>Github &mdash; personal repositories</h2>


<p>When you&#8217;re dealing directly with Github, on a personal project or as the project owner, your repositories will look like this:</p>

<p><img src="http://www.jagregory.com/images/remote-3.png" alt="Figure 3" /></p>

<p>To push and pull changes between your local and your github repositories, just issue the push and pull commands with the origin remote:</p>

<pre>git push origin
git pull origin</pre>


<p>You can set the defaults for these commands too, so the origin isn&#8217;t even necessary in a lot of cases.</p>

<h2>Github &mdash; receiving contributions</h2>


<p>As a project owner, you&#8217;ll sometimes have to deal with contributions from other people. Each contributor will have their own github repository, and they&#8217;ll issue you with a pull request.</p>

<p><img src="http://www.jagregory.com/images/remote-4.png" alt="Figure 4" /></p>

<p>There&#8217;s no direct link to push between these two repositories; they&#8217;re unmanned. To manage changes from contributors, you need to involve your local repository.</p>

<p>You can think of this as taking the shape of a V.</p>

<p><img src="http://www.jagregory.com/images/remote-5.png" alt="Figure 5" /></p>

<p>You need to register their github repository as a remote on your local, pull in their changes, merge them, and push them up to your github. This can be done as follows:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git remote add contributor contributor_repository.git
</span><span class='line'>git pull contributor branch
</span><span class='line'>git push</span></code></pre></td></tr></table></div></figure>




<h2>Github &mdash; providing contributions</h2>


<p>Do exactly as you would your own personal project. Local changes, pushed up to your github fork; then issue a pull request. That&#8217;s all there is to it.</p>

<h2>Github &mdash; the big picture</h2>


<p>Here&#8217;s how to imagine the whole process, think of it as an N shape.</p>

<p><img src="http://www.jagregory.com/images/remote-6.png" alt="Figure 6" /></p>

<p>On the left is the contributor, and the right is the project. Flow goes from bottom left, along the lines to the top right.</p>

<ol>
<li>Contributor makes a commit in their local repository</li>
<li>Contributor pushes that commit to their github</li>
<li>Contributor issues a pull request to the project</il>
<li>Project lead pulls the contributor&#8217;s change into their local repository</li>
<li>Project lead pushes the change up to the project github</li>
</ol>


<p>That&#8217;s as complicated as it gets.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Behaviours in MSpec]]></title>
    <link href="http://www.jagregory.com/writings/behaviours-in-mspec/"/>
    <updated>2010-01-22T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/behaviours-in-mspec</id>
    <content type="html"><![CDATA[<blockquote>Cross posted to <a href="http://www.lostechies.com/blogs/jagregory/archive/2010/01/18/behaviours-in-mspec.aspx">Los Techies</a></blockquote>




<p><a href="http://github.com/machine/machine.specifications">MSpec</a> is awesome, I think it&#8217;s praised by myself and others enough for that particular point to not need any expansion; however, there is a particular feature I would like to highlight that hasn&#8217;t really got a lot of press: behaviours.</p>




<p>Behaviours define reusable specs that encapsulate a particular set of, you guessed it, behaviours; you&#8217;re then able to include these specs in any context that exhibits a particular behaviour.</p>




<p>Lets go with the cliche&#8217;d Vehicle example. Given an <code>IVehicle</code> interface, with <code>Car</code> and <code>Motorbike</code> implementations; these all expose a <code>StartEngine</code> method and some properties reflecting the state of the vehicle. We&#8217;ll start the engine and verify that it is actually started, whether it&#8217;s got anything on the rev counter, and whether it&#8217;s killing our planet in the process (zing!).</p>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">interface</span> <span class="n">IVehicle</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">void</span> <span class="nf">StartEngine</span><span class="p">();</span>
</span><span class='line'>  <span class="kt">bool</span> <span class="n">IsEngineRunning</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>  <span class="kt">bool</span> <span class="n">IsPolluting</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">RevCount</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">Car</span> <span class="p">:</span> <span class="n">IVehicle</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">public</span> <span class="kt">bool</span> <span class="n">IsEngineRunning</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="k">void</span> <span class="nf">StartEngine</span><span class="p">()</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="c1">// use your imagination...</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">Motorbike</span> <span class="p">:</span> <span class="n">IVehicle</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">public</span> <span class="kt">bool</span> <span class="n">IsEngineRunning</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="k">void</span> <span class="nf">StartEngine</span><span class="p">()</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="c1">// use your imagination...</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<p>Those are our classes, if rather contrived, but they&#8217;ll do. Now what we need to do is write some specs for them.</p>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">when_a_car_is_started</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">Establish</span> <span class="n">context</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Car</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">Because</span> <span class="n">of</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">StartEngine</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">It</span> <span class="n">should_have_a_running_engine</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">IsEngineRunning</span><span class="p">.</span><span class="n">ShouldBeTrue</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">It</span> <span class="n">should_be_polluting_the_atmosphere</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">IsPolluting</span><span class="p">.</span><span class="n">ShouldBeTrue</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">It</span> <span class="n">should_be_idling</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">RevCount</span><span class="p">.</span><span class="n">ShouldBeBetween</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">1000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">static</span> <span class="n">Car</span> <span class="n">vehicle</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">when_a_motorbike_is_started</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">Establish</span> <span class="n">context</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Motorbike</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">Because</span> <span class="n">of</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">StartEngine</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">It</span> <span class="n">should_have_a_running_engine</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">IsEngineRunning</span><span class="p">.</span><span class="n">ShouldBeTrue</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">It</span> <span class="n">should_have_a_running_engine</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">IsEngineRunning</span><span class="p">.</span><span class="n">ShouldBeTrue</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">It</span> <span class="n">should_be_polluting_the_atmosphere</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">IsPolluting</span><span class="p">.</span><span class="n">ShouldBeTrue</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">It</span> <span class="n">should_be_idling</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">RevCount</span><span class="p">.</span><span class="n">ShouldBeBetween</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">1000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">static</span> <span class="n">Motorbike</span> <span class="n">vehicle</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<p>Those are our specs, there&#8217;s not much in there but already you can see that we&#8217;ve got duplication. Our two contexts contain identical specs, they&#8217;re the same in what they&#8217;re verifying, the only difference is the vehicle instance. This is where behaviours can come in handy.</p>




<p>With behaviours we can extract the specs and make them reusable. Lets do that.</p>




<p>Create a class for your behaviour and adorn it with the <code>Behaviors</code> attribute &mdash; this ensures MSpec recognises your class as a behaviour definition and not just any old class &mdash; then move your specs into it.</p>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="na">[Behaviors]</span>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">VehicleThatHasBeenStartedBehaviors</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">protected</span> <span class="k">static</span> <span class="n">IVehicle</span> <span class="n">vehicle</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">It</span> <span class="n">should_have_a_running_engine</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">IsEngineRunning</span><span class="p">.</span><span class="n">ShouldBeTrue</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">It</span> <span class="n">should_have_a_running_engine</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">IsEngineRunning</span><span class="p">.</span><span class="n">ShouldBeTrue</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">It</span> <span class="n">should_be_polluting_the_atmosphere</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">IsPolluting</span><span class="p">.</span><span class="n">ShouldBeTrue</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">It</span> <span class="n">should_be_idling</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">RevCount</span><span class="p">.</span><span class="n">ShouldBeBetween</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">1000</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<p>We&#8217;ve now got our specs in the behaviour, and have defined a field for the vehicle instance itself (it won&#8217;t compile otherwise). This is our behaviour complete, it defines a set of specifications that verify that a particular behaviour.</p>




<p>Lets hook that behaviour into our contexts from before:</p>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">when_a_car_is_started</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">Establish</span> <span class="n">context</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Car</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">Because</span> <span class="n">of</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">StartEngine</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">Behaves_like</span><span class="p">&lt;</span><span class="n">VehicleThatHasBeenStartedBehaviors</span><span class="p">&gt;</span> <span class="n">a_started_vehicle</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">protected</span> <span class="k">static</span> <span class="n">Car</span> <span class="n">vehicle</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">when_a_motorbike_is_started</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">Establish</span> <span class="n">context</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Motorbike</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">Because</span> <span class="n">of</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
</span><span class='line'>    <span class="n">vehicle</span><span class="p">.</span><span class="n">StartEngine</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">Behaves_like</span><span class="p">&lt;</span><span class="n">VehicleThatHasBeenStartedBehaviors</span><span class="p">&gt;</span> <span class="n">a_started_vehicle</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">protected</span> <span class="k">static</span> <span class="n">Motorbike</span> <span class="n">vehicle</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<p>We&#8217;ve now put to use the <code>Behaves_like</code> feature, which references our behaviour class and imports the specs into the current context. Now when you run your specs, the specs from our behaviour are imported and run in each context. We don&#8217;t need to assign anything to that field, just defining it is enough; the name you choose for the field is what&#8217;s used by MSpec as the description for what your class is behaving like. In our case this is translated roughly to <em>&#8220;when a motorbike is started it behaves like a started vehicle&#8221;</em>.</p>




<p>There are a couple of things you need to be aware of to get this to work: your fields must be <code>protected</code>, both in the behaviour and the contexts; and the fields must have identical names. If you don&#8217;t get these two correct your behaviour won&#8217;t be hooked up properly. It&#8217;s also good to know that the fields <strong>do not</strong> need to have the same type, as long as the value from your context is assignable to the field in the behaviour then you&#8217;re good; this is key to defining reusable specs for classes that share a sub-set of functionality.</p>




<p>In short, behaviours are an excellent way of creating reusable specs for shared functionality, without the need to create complex inheritance structures. It&#8217;s not a feature you should use lightly, as it can greatly reduce the readability of your specs, but it is a good feature if you&#8217;ve got a budding spec explosion nightmare on your hands.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git's guts: Merging and rebasing]]></title>
    <link href="http://www.jagregory.com/writings/gits-guts-merging-and-rebasing/"/>
    <updated>2009-11-27T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/gits-guts-merging-and-rebasing</id>
    <content type="html"><![CDATA[<blockquote>Cross posted to <a href="http://www.lostechies.com/blogs/jagregory/archive/2009/11/27/git-guts-merging-and-rebasing.aspx">Los Techies</a></blockquote>




<p>Here we go again, explaining the internals of Git with the intention of helping you understand what you&#8217;re doing day-to-day. Last time I covered <a href="http://www.jagregory.com/writings/gits-guts-branches-head-and-fast-forwards">branches, HEAD, and fast-forwarding</a>. Today we&#8217;ll dive into the guts of merging and rebasing.</p>




<h3>Merging branches</h3>




<p>You&#8217;ve probably merged before. You do it when you want the changes from one branch in another. The principal is the same in Git as it is most other source control systems, but the implementation differs.</p>




<p>Given the following commit structure, consisting of two branches created from the same commit, each with two commits after the branching occurred.</p>


<p><img src="http://www.jagregory.com/images/GitGuts2_Figure1.png" alt="Figure 1" /></p>

<p>When these two branches are merged together, this is the structure that results:</p>


<p><img src="http://www.jagregory.com/images/GitGuts2_Figure2.png" alt="Figure 1" /></p>

<p>The top-most commit, the red one, is a new commit made by the merge; the merge commit is what reminds Git that a merge occurred next time it&#8217;s showing the history. This commit is special, as it contains multiple parent&#8217;s in it&#8217;s meta-data; these multiple parent&#8217;s allow Git to follow the two trees of commits that constituted the branches that were merged.</p>




<p>One difference in how Git handles merges compared to many other SCMs is that it preserves the commits that were made in both branches. In other systems merges are often represented as a single commit containing the squashed contents of all the commits that were made in the branch being merged in. Git doesn&#8217;t do this (by default, you can tell it to if you want), and therefore preserves all the commits just as they were made; this is quite nice, as it proves incredibly useful to be able to track the origin of changes beyond the point of a merge.</p>




<p>When you merge two branches, it&#8217;s interesting to know that none of the commits are altered in the process. Just bare this in mind for now, I&#8217;ll explain why this is good to know later.</p>




<p>After a merge, if you were to view the history, you&#8217;d see it shown like the previous example, commits in chronological order; the feature branch commits are interspersed between the master commits.</p>


<p><img src="http://www.jagregory.com/images/GitGuts2_Figure2.png" alt="Figure 1" /></p>

<p>Yet no commits have been altered in the merge, so how are the commits in a different order? Well, they&#8217;re not, Git&#8217;s just showing you it in the order you expect it to be in. Internally the structure is still as below:</p>


<p><img src="http://www.jagregory.com/images/GitGuts2_Figure3.png" alt="Figure 1" /></p>

<p>The merge commit instructs Git to walk the two trees while building the history, and it just displays the results in chronological order. This makes more sense if you recall that Git commits don&#8217;t hold differences like other SCM systems, instead they each contain a snapshot of the complete repository; while in another SCM the ordering of commits is vital &mdash; otherwise the diffs wouldn&#8217;t build a valid file &mdash; Git is able to infer order without affecting the repository contents.</p>




<p>Looking at it in commit order, you can quite easily see how Git flattens the history to be perceived as linear without ever having to touch any of the original commits.</p>




<h4>What happens if there&#8217;s a merge conflict?</h4>




<p>We&#8217;ve all dealt with conflicts in merging before. They typically happen when changes are made to the same file in two branches, in a way that cannot be easily merged (two people edit the same line, for example).</p>




<p>Git&#8217;s commit&#8217;s are immutable though, so how are the changes that you need to make to resolve these conflicts saved? Simple. The merge commit is a regular commit with some extra meta-data, and so it capable of containing changes itself; merge conflict changes are stored in the merge commit. Again, no changes necessary to the original commits.</p>




<h3>Git objects, immutability, and rewriting history</h3>




<p>A Git repository is comprised of objects. A file is a blob object with a name attached to it; if you have two files with the same content, that&#8217;s just two names to a single blob. A directory is a tree object, which is comprised of other trees and blobs. A commit is an object that references a tree object, which is the state of the repository at the time of committing.</p>




<blockquote>To read more about git objects, I&#8217;d definitely recommend you read the <a href="http://book.git-scm.com">Git community book</a>.</blockquote>




<p>Git objects are immutable. To change an object after it&#8217;s been created is impossible, you have to recreate the object with any changes made. Even operations that seem to modify objects actually don&#8217;t; <code>commit --amend</code> is a typical example, that deletes and re-creates the commit rather than actually amending it.</p>




<p>I mentioned that merges don&#8217;t rewrite history, and that it&#8217;s a good thing. Now I&#8217;ll explain why. When you rewrite history, you do so by making changes to commits that ripple up the commit tree; when this happens, it can cause complications when others merge from you. Given a series of commits, like so:</p>


<p><img src="http://www.jagregory.com/images/GitGuts2_Figure4.png" alt="Figure 1" /></p>

<p>You then share these commits with another user.</p>


<p><img src="http://www.jagregory.com/images/GitGuts2_Figure5.png" alt="Figure 1" /></p>

<p>John now has Michael&#8217;s commits in his repository; however, Michael notices he&#8217;s made a typo in the first commit message, so he amends the commit message. The change in the message requires the commit be recreated. With that first commit recreated, the second commit now has an invalid parent reference, so that commit has to be recreated with the new reference; this recreation ripples it&#8217;s way up the tree, recreating each commit with a new parent. Michael has completely rewritten his tree&#8217;s history.</p>


<p><img src="http://www.jagregory.com/images/GitGuts2_Figure6.png" alt="Figure 1" /></p>

<p>Notice all the commit hashes have changed in Michael&#8217;s repository, and John&#8217;s now don&#8217;t match. If Michael was then to make a new commit to his repository, and John tried to merge that change into his repository, Git would get very upset because the new commit would reference a commit that doesn&#8217;t exist in John&#8217;s repository.</p>




<p><strong>The golden rule is:</strong> rewriting history is fine as long as the commits that will be affected haven&#8217;t been made public.</p>




<h3>Rebasing</h3>




<p>The purpose of a rebase is the same as a merge, to bring two tree&#8217;s of commits together. It differs in it&#8217;s approach. Rebasing is a seriously sharp tool. Very powerful, but pretty easy to cut yourself with it.</p>




<p>When you rebase one branch onto another, Git undoes any changes you&#8217;ve made in the target branch, brings it up to date with the changes made in the source branch, then replays your commits on top. This sounds quite strange, so I&#8217;ll go over it step-by-step.</p>




<p>You start with your diverged branches:</p>


<p><img src="http://www.jagregory.com/images/GitGuts2_Figure7.png" alt="Figure 1" /></p>

<p>If you then rebase feature onto master, Git undoes the changes in master.</p>


<p><img src="http://www.jagregory.com/images/GitGuts2_Figure8.png" alt="Figure 1" /></p>

<p>The history of both branches is now the same, master has been updated to reflect feature; the new commits that were made in master are now detached, floating in the repository without anything referencing them.</p>




<p>The next step is to replay the master commits onto the new structure. This is done one-by-one, and can sometimes result in conflicts that will need to be handled like any merge.</p>




<p>After replaying the repository will look like this:</p>


<p><img src="http://www.jagregory.com/images/GitGuts2_Figure9.png" alt="Figure 1" /></p>

<p>The master branch commits are now on the top of the stack, after the commits from the feature branch.</p>




<p>You should recall that commits are immutable, and for changes to be made commits need to be recreated. A rebase is a destructive operation, as it has to rewrite commits to be able to work. In this case, the commits from feature have been unaffected, but the master commits have been assigned new parents (and thus rewritten). What&#8217;s also noticeable is there&#8217;s a lack of a merge commit, which isn&#8217;t needed because the commits have been integrated into the tree; any conflicts are stored in the amended commits, rather than in a merge commit.</p>




<p>The rewriting of commits in a rebase is what makes it a dangerous operation to perform on any branch that has already been pushed to the public (or specifically, that the changes affected by the rebase have already been pushed to the public). A rebase can cause problems upstream, like mentioned in the previous section.</p>




<p>Rebase has it&#8217;s place though. If you&#8217;re working locally and haven&#8217;t yet pushed your changes public, it can be a useful tool. Rebase can be used to pull in changes from upstream in the order that the upstream repository has them, and your local changes (that can be rewritten because you&#8217;re the only one with them) can be replayed on-top; this is a really easy way to keep your repository up-to-date with an authoritative source. You can also use Rebase to manage local branches that you don&#8217;t necessarily want polluting the history with merge markers.</p>




<h3>When to rebase and when to merge?</h3>




<p>Merge when you&#8217;ve already made changes public, and when you want to indicate that two tree&#8217;s have converged. Rebase pretty much any other time.</p>




<p>That&#8217;s it for this time. Same deal as last time, if you have anything you&#8217;d like me to cover I&#8217;ll nail it in the next one.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git's guts: Branches, HEAD, and fast-forwards]]></title>
    <link href="http://www.jagregory.com/writings/gits-guts-branches-head-and-fast-forwards/"/>
    <updated>2009-11-25T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/gits-guts-branches-head-and-fast-forwards</id>
    <content type="html"><![CDATA[<blockquote>Cross posted to <a href="http://www.lostechies.com/blogs/jagregory/archive/2009/11/25/git-s-guts-branches-head-and-fast-forwards.aspx">Los Techies</a></blockquote>




<p>Lets get some learning done. There are a few questions that keep cropping up when I introduce people to Git, so I thought I&#8217;d post some answers as a mini-series of blog posts. I&#8217;ll cover some fundamentals, while trying not to retread too much ground that the fantastic <a href="http://book.git-scm.com">Git community book</a> already covers so well. Instead I&#8217;m going to talk about things that should help you understand what you and Git are doing day-to-day.</p>




<h3>What&#8217;s a branch?</h3>




<p>I know what you&#8217;re thinking. <em>&#8220;C&#8217;mon, we know what a branch is&#8221;</em>. A branch is a copy of a source tree, that&#8217;s maintained separately from it&#8217;s parent; that&#8217;s what we perceive a branch to be, and that&#8217;s how we&#8217;re used to dealing with them. Sometimes they&#8217;re physical copies (VSS and TFS), other times they&#8217;re lightweight copies (SVN), but they&#8217;re copies non-the-less. Or are they?</p>




<p>Lets look at it a different way. <em>The Git way</em>.</p>




<p>Git works a little differently than most other version control systems. It doesn&#8217;t store changes using <a href="http://en.wikipedia.org/wiki/Delta_encoding">delta encoding</a>, where complete files are built up by stacking differences contained in each commit. Instead, in Git each commit stores a snapshot of how the repository looked when the commit occurred; a commit also contains a bit of meta-data, author, date, but more importantly a reference to the parent of the commit (the previous commit, usually).</p>




<p>That&#8217;s a bit weird, I know, but bare with me.</p>




<p>So what is a branch? Nothing more than a pointer to a commit (with a name). There&#8217;s nothing physical about it, nothing is created, moved, copied, nothing. A branch contains no history, and has no idea of what it consists of beyond the reference to a single commit.</p>




<p>Given a stack of commits:</p>


<p><img src="http://www.jagregory.com/images/GitGuts1_Figure1.png" alt="Figure 1" /></p>

<p>The branch references the newest commit. If you were to make another commit in this branch, the branch&#8217;s reference would be updated to point at the new commit.</p>


<p><img src="http://www.jagregory.com/images/GitGuts2_Figure2.png" alt="Figure 2" /></p>

<p>The history is built up by recursing over the commits through each&#8217;s parent.</p>




<h3>What&#8217;s HEAD?</h3>




<p>Now that you know what a branch is, this one is easy. <code>HEAD</code> is a reference to the latest commit in the branch you&#8217;re in.</p>




<p>Given these two branches:</p>


<p><img src="http://www.jagregory.com/images/GitGuts1_Figure3.png" alt="Figure 3" /></p>

<p>If you had master checked out, <code>HEAD</code> would reference <code>e34fa33</code>, the exact same commit that the master branch itself references. If you had feature checked out, <code>HEAD</code> would reference <code>dde3e1</code>. With that in mind, as both <code>HEAD</code> and a branch is just a reference to a commit, it is sometimes said that <code>HEAD</code> points to the current branch you&#8217;re on; while this is not strictly true, in most circumstances it&#8217;s close enough.</p>




<h3>What&#8217;s a fast-forward?</h3>




<p>A fast-forward is what Git does when you merge or rebase against a branch that is simply ahead the one you have checked-out.</p>




<p>Given the following branch setup:</p>


<p><img src="http://www.jagregory.com/images/GitGuts1_Figure4.png" alt="Figure 4" /></p>

<p>You&#8217;ve got both branches referencing the same commit. They&#8217;ve both got exactly the same history. Now commit something to feature.</p>


<p><img src="http://www.jagregory.com/images/GitGuts1_Figure5.png" alt="Figure 5" /></p>

<p>The <code>master</code> branch is still referencing <code>7ddac6c</code>, while <code>feature</code> has advanced by two commits. The <code>feature</code> branch can now be considered ahead of <code>master</code>.</p>




<p>It&#8217;s now quite easy to see what&#8217;ll happen when Git does a fast-forward. It simply updates the <code>master</code> branch to reference the same commit that <code>feature</code> does. No changes are made to the repository itself, as the commits from <code>feature</code> already contain all the necessary changes.</p>




<p>Your repository history would now look like this:</p>


<p><img src="http://www.jagregory.com/images/GitGuts1_Figure6.png" alt="Figure 6" /></p>

<h3>When doesn&#8217;t a fast-forward happen?</h3>




<p>Fast-forwards don&#8217;t happen in situations where changes have been made in the original branch and the new branch.</p>


<p><img src="http://www.jagregory.com/images/GitGuts1_Figure7.png" alt="Figure 7" /></p>

<p>If you were to merge or rebase <code>feature</code> onto <code>master</code>, Git would be unable to do a fast-forward because the trees have both diverged. Considering Git commits are immutable, there&#8217;s no way for Git to get the commits from <code>feature</code> into <code>master</code> without changing their parent references.</p>




<p>For more info on all this object malarky, I&#8217;d recommend reading the <a href="http://book.git-scm.com">Git community book</a>.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fluent NHibernate 1.0 RTM]]></title>
    <link href="http://www.jagregory.com/writings/fluent-nhibernate-10-rtm/"/>
    <updated>2009-08-29T00:00:00+10:00</updated>
    <id>http://www.jagregory.com/writings/fluent-nhibernate-10-rtm</id>
    <content type="html"><![CDATA[<p>It&#8217;s <a href="http://fluentnhibernate.org/downloads">here</a>.</p>

<p>For those of you that don&#8217;t know, <a href="http://fluentnhibernate.org">Fluent NHibernate</a> is for helping you map entities with <a href="http://nhforge.org">NHibernate</a>. It&#8217;s based firmly on the practice of <a href="http://en.wikipedia.org/wiki/Convention_over_configuration">convention-over-configuration</a>, and can be used in a mapping-per-class style using our <a href="http://wiki.fluentnhibernate.org/Fluent_mapping">fluent interface</a>, or let our <a href="http://wiki.fluentnhibernate.org/Auto_mapping">automapper</a> map your entities itself.</p>

<p>This release introduces a few significant changes, and a lot of insignificant ones. You should refer to the <a href="http://wiki.fluentnhibernate.org/Release_notes_1.0">1.0 release notes</a> for an overview of what&#8217;s changed.</p>

<p>The <a href="http://wiki.fluentnhibernate.org">wiki</a> has also been upgraded to use different software which should hopefully stop people being blocked, and make it a bit more stable; the upgrade included completely rewriting all of the pages, so don&#8217;t anyone say that it&#8217;s out of date.</p>

<p>You can get the binaries from the our <a href="http://fluentnhibernate.org/downloads">downloads page</a>, or get the source from the <a href="http://github.com/jagregory/fluent-nhibernate">github site</a>.</p>

<p>Special thanks go out to the Fluent NHibernate team, Paul Batum, Hudson Akridge, Andrew Stewart, and Stuart Childs. Each of them has put in time and effort above what was asked of them, and they&#8217;ve all felt guilty when not contributing, which is great. Thanks also to all the testers and contributors we&#8217;ve had over the months. Specifically Darko Conrad, for finding about 30 separate issues with the release candidiate; Everett Muniz and his subclasses, who now has a test of his own; and Kevin Dente, for deciding to moan about our method names only <em>after</em> months of work and a release candidate. I owe everyone beers if ever I&#8217;m in your area.</p>

<p>Fabio Maulo, Ayende, and the rest of the NHibernate team: Thanks for a great tool. NHibernate is a shining example of all that is good in open source in the .Net world.</p>

<p>&#8230;and with that, I&#8217;m going on <a href="http://maps.google.co.uk/maps?f=d&source=s_d&saddr=Sydney&daddr=Brisbane+to:Cairns&hl=en&geocode=&mra=ls&sll=-25.656382,152.880249&sspn=1.383954,1.851196&ie=UTF8&ll=-25.522615,152.358398&spn=22.065278,29.619141&z=5">holiday</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Preventing debugger property evaluation for side-effect laden properties]]></title>
    <link href="http://www.jagregory.com/writings/preventing-debugger-property-evaluation-side-effects/"/>
    <updated>2009-08-18T00:00:00+10:00</updated>
    <id>http://www.jagregory.com/writings/preventing-debugger-property-evaluation-side-effects</id>
    <content type="html"><![CDATA[<p>Property getters with side-effects, now there&#8217;s a controversial subject if ever I saw one. Don&#8217;t do it is the rule; as with any rule though, there&#8217;s generally an exception that proves it. If you&#8217;re in this situation and you genuinely do have a scenario that requires a property getter to have side-effects, then there&#8217;s a side-effect (ha!) that you should be aware of.</p>




<p><strong>The debugger evaluates property getters when showing it&#8217;s locals and autos windows.</strong> While this feature is indispensable in most cases, it plays havoc with our property-with-side-effects. What the debugger does is call the getter to present it&#8217;s value in the autos window, at the same time firing our code that has a side-effect. From there you have pretty confusing behavior with code seemingly running itself.</p>




<p>My exception to the rule is mutator properties in a fluent interface. You can often find properties in fluent interfaces that when touched alter the behavior of the next method called.</p>




<p>For example:</p>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="kt">string</span> <span class="k">value</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="n">Is</span><span class="p">.</span><span class="n">Null</span><span class="p">(</span><span class="k">value</span><span class="p">)</span>      <span class="c1">// returns true</span>
</span><span class='line'><span class="n">Is</span><span class="p">.</span><span class="n">Not</span><span class="p">.</span><span class="n">Null</span><span class="p">(</span><span class="k">value</span><span class="p">)</span>  <span class="c1">// returns false</span>
</span></code></pre></td></tr></table></div></figure>




<p>The Is class would contain a value tracking whether the next call would be inverted or not, and the Not property would flip that value when called.</p>




<p>Now assume this, you&#8217;re using <code>Is.Null(value)</code> and you set a breakpoint on it. Your autos window has expanded Is and shows the Not property, what&#8217;s just happened? The debugger has now called Not and altered your state! Undesirable.</p>




<p><a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.debuggerbrowsableattribute.aspx">DebuggerBrowsable attribute</a> to the rescue; this attribute when used with the DebuggerBrowsableState.Never parameter instructs Visual Studio to never inspect the property you apply it to. Your property won&#8217;t appear in the autos or locals window, and if you expand the tree of an instance containing the property it will show up with a Browsing Disabled message; you can then force it to evaluate the property, but at least it doesn&#8217;t do it automatically.</p>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">private</span> <span class="kt">bool</span> <span class="n">inverted</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="na">[DebuggerBrowsable(DebuggerBrowsableState.Never)]</span>
</span><span class='line'><span class="k">public</span> <span class="n">Is</span> <span class="n">Not</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">get</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="n">inverted</span> <span class="p">=</span> <span class="p">!</span><span class="n">inverted</span><span class="p">;</span>
</span><span class='line'>    <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<p>Sticking the DebuggerBrowsable attribute on your Not property prevents the debugger from hitting it and inverting the switch.</p>




<p>So there you go, if your property-with-side-effects is being invoked by the debugger, you can use the DebuggerBrowsableAttribute to prevent it.</p>




<blockquote>By the way, I&#8217;m not advocating properties with side-effects&#8230;</blockquote>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fluent NHibernate 1.0RC]]></title>
    <link href="http://www.jagregory.com/writings/fluent-nhibernate-10rc/"/>
    <updated>2009-08-16T00:00:00+10:00</updated>
    <id>http://www.jagregory.com/writings/fluent-nhibernate-10rc</id>
    <content type="html"><![CDATA[<p>It&#8217;s nearly here, at long last <a href="http://fluentnhibernate.org">Fluent NHibernate</a> has nearly reached 1.0. Now starts the official public testing of our 1.0RC.</p>

<p>You can read the <a href="http://wiki.fluentnhibernate.org/Release_notes_1.0">release notes</a> on the wiki for more information on what&#8217;s changed. There have been a lot of small breaking changes in the fluent interface, mostly reducing it&#8217;s verbosity, and a few larger changes elsewhere. Don&#8217;t expect to download this and have it <em>just work</em>, because it won&#8217;t; hopefully it shouldn&#8217;t be too painful though.</p>

<p>My plan is that this is a very quick turnaround for a release candidate. It&#8217;s already undergone some heavy testing from some respected volunteers, but I wanted to get it into the public eye for a week or so before release. Ideally the RTM release won&#8217;t differ from this one at all, but we&#8217;ll see.</p>

<p>You can find the binaries on our <a href="http://fluentnhibernate.org/downloads">downloads page</a>, and it&#8217;s now included in the binary build releases too.</p>

<p>Any questions should be directed to the <a href="http://groups.google.com/group/fluent-nhibernate">mailing-list</a>, and issues onto our <a href="http://code.google.com/p/fluent-nhibernate/issues/list">issue list</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git and command-line fear]]></title>
    <link href="http://www.jagregory.com/writings/git-and-command-line-fear/"/>
    <updated>2009-07-20T00:00:00+10:00</updated>
    <id>http://www.jagregory.com/writings/git-and-command-line-fear</id>
    <content type="html"><![CDATA[<blockquote><p>Cross-posted to <a href="http://www.lostechies.com/blogs/jagregory/archive/2009/07/20/git-s-and-command-line-fear.aspx">Los Techies</a></p></blockquote>

<p><a href="http://git-scm.org">Git</a> has been gaining a lot of traction lately, and rightly so. I&#8217;ve used it for a couple of years now, for all my projects (<a href="http://fluentnhibernate.org">Fluent NHibernate</a> and <a href="http://docu.jagregory.com">Docu</a> being the prominent ones), but something that hasn&#8217;t changed is the tag-line of &#8220;but Windows support isn&#8217;t very good!&#8221;. What you quickly learn is that when people say that, they actually mean there isn&#8217;t a Visual Studio plug-in or some similar all-singing all-dancing GUI; this is a dire misrepresentation of Git, because it&#8217;s tooling on Windows is excellent if your definition of tooling includes the command-line.</p>

<p>It&#8217;s something ingrained in Windows developers, they hate the command-line. There&#8217;s a very good chance that if you encounter a Windows developer that does enjoy using the command-line it&#8217;s because they&#8217;ve also worked on another platform or in another environment that encourages command-line use (Rails is a good example). I&#8217;ve tried various ways of encouraging people to experiment, but very few work without being able to sit down and just show them something. It&#8217;s very much like R# adoption, nobody thinks it&#8217;ll speed them up until they see how fast someone else can be.</p>

<p>Back onto Git. If you don&#8217;t like what Git does, then that&#8217;s fine, but don&#8217;t label yourself as Alt.Net or a continuous improver if this sounds like you: &#8220;I define myself by choosing the best tool for each situation, but there&#8217;s no way you&#8217;ll get me using the command-line.&#8221; Way to go, oh open-minded one. Try it, you might like it.</p>

<p>The other techies have been posting some great <a href="http://www.lostechies.com/blogs/tags/git/default.aspx">Git posts</a> which can help you get up to speed. I hope to contribute, with less bile, soon.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What's been happening in Fluent NHibernate land?]]></title>
    <link href="http://www.jagregory.com/writings/whats-been-happening-in-fluent-nhibernate-land/"/>
    <updated>2009-04-28T00:00:00+10:00</updated>
    <id>http://www.jagregory.com/writings/whats-been-happening-in-fluent-nhibernate-land</id>
    <content type="html"><![CDATA[<blockquote>Cross-posted to <a href="http://jagregory.lostechies.com/archive/2009/04/28/what-s-been-happening-in-fluent-nhibernate-land.aspx">Los Techies</a></blockquote>


<p><a href="http://www.fluentnhibernate.org">Fluent NHibernate</a> has seen a flurry of development followed by a complete lack of commits, I figure it&#8217;s time to let everyone know what&#8217;s going on.</p>

<p><strong>The Short Version</strong></p>

<p>We&#8217;re rewriting the internals. We have 100% of tests passing, but still can&#8217;t guarantee no regressions. Stuff may break, if it does, <a href="http://groups.google.com/group/fluent-nhibernate">tell us</a>. It&#8217;ll be worth it.</p>

<p><strong>The Long Version</strong></p>

<p>Once upon a time&#8230;</p>

<p>Fluent NHibernate at it&#8217;s core is a fluent interface over xml generation. We use the series of methods you call in your mappings to build up an in-memory hbm xml document that we then feed to NHibernate. Slowly, as we&#8217;ve started to support more and more of NHibernate&#8217;s features, we&#8217;ve started to find flaws in our architecture. It amounts to us not having enough separation of concerns; our fluent interface is generating xml, I think most people would say that&#8217;s not a good thing. Our xml is being generated too soon in the cycle to allow us to do more clever things that&#8217;d improve the user&#8217;s experience. That&#8217;s where the quiet time comes in.</p>

<p><a href="http://www.paulbatum.com">Paul Batum</a> undertook the task of redesigning the internals of Fluent NHibernate to be something much more scalable. I&#8217;ll leave the details out for now (maybe a future post), but it amounts to a intermediary layer being introduced between the fluent interface and the xml generation. We&#8217;ve dubbed this the Semantic Model, and it&#8217;s that which is now generated by the fluent interface, then later translated into xml. This added abstraction allows us to do things that weren&#8217;t possible while we were just generating straight xml.</p>

<p>Whilst you wont see any immediate improvements while everything is being converted, the extra layer allows us to inspect the model before it is converted to xml; this gives us some immense capabilities, such as allowing subclasses to be separate from their parent mapping, create reusable component mappings, improve relationship support etc&#8230; We&#8217;re pretty much limited only by what we can imagine now, rather than by architectural decisions.</p>

<p>However, we have a dilemma. The semantic-model branch has deviated so much from trunk we&#8217;ve got a major merge problem. A merge is pretty much out of the question actually, because there&#8217;s barely any commonality between the two streams at all. It was then assumed that the branch would eventually replace trunk (we&#8217;d just rename trunk to a tag, then rename the semantic-model branch to trunk), and all we needed to do was get the branch up-to-date with the features of trunk. Little did we realise we were essentially committing to something that I typically oppose, a complete rewrite! I&#8217;ve never been in a situation where that&#8217;s ever been a good idea, and yet here we are, responsible for our own destiny as it was, and we&#8217;d chosen a rewrite!</p>

<p>A few weeks went by with very little work happening. I think we&#8217;d all started feeling demoralised by the idea of re-implementing most of the features from trunk using the new design. It was a worthwhile endeavor, definitely, but just very uninteresting. We repeatedly swore that we&#8217;d get this done, but all the while we felt less inclined to support trunk because every new feature meant a new feature to port too. We stopped.</p>

<p>At that point <a href="http://www.bestguesstheory.com/">Hudson Akridge</a>, our newest contributor, had the balls to tell me that he thought what we were doing felt pretty futile. At that moment I gained a great deal of respect for him, as it&#8217;s something that was in the back of my mind for some time but I wasn&#8217;t ready to face yet. It was that which got me moving again.</p>

<p>I sat down over a long weekend and took on the mammoth task of merging our rewrite branch and trunk, with the aim of allowing the existing code to exist alongside the new code; this approach, if it worked, would allow us to convert existing features at our own pace while still writing new features for the cleaner codebase. After a lot of unpleasant hacking of nice code, I managed to get all our existing tests passing while utilising the semantic model behind the scenes. Our old code still directly generates xml, which then gets injected into the semantic model via a nasty shortcut. It feels dirty, because I&#8217;ve had to comprimise some good code to get it working, but in a way I think that&#8217;s a good thing; if code is nasty, we&#8217;re all less likely to be content with it. The main goal was achieved though, and that was to allow us to work at our own pace on trunk.</p>

<p>Where we stand now is three branches, trunk, integration, and semantic-model. Over the next day or so I am going to merge integration with trunk, which will mean the semantic model will be in use for new features. From there we can slowly migrate all the original code to use our new semantic model, all the while adding new features using it, then eventually remove the duct-tape that&#8217;s holding the legacy code to the new code and dump the old stuff.</p>

<p>This is where I&#8217;ll give you a little warning: although we have 100% of tests passing, we don&#8217;t have 100% coverage. There may be some regressions that we aren&#8217;t aware of. If anyone finds anything broken that was working before, contact us immediately on the <a href="groups.google.com/group/fluent-nhibernate">mailing list</a> or via the <a href="http://code.google.com/p/fluent-nhibernate/issues/list">issues list</a> and we&#8217;ll correct it. Regressions will be treated with the highest priority over any other work.</p>

<p>That&#8217;s it, you now know more about what&#8217;s happening with Fluent NHibernate than you ever wanted to. I hope this sheds a little light onto what&#8217;s been happening with us, and perhaps why your patch hasn&#8217;t been applied as quickly as you would&#8217;ve liked.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[I'm a Los Techie]]></title>
    <link href="http://www.jagregory.com/writings/im-a-los-techie/"/>
    <updated>2009-03-28T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/im-a-los-techie</id>
    <content type="html"><![CDATA[Just to let anyone know that hasn&#8217;t heard by other means, I&#8217;m now blogging at <a href="http://lostechies.com">Los Techies</a>. I&#8217;m going to cross-post between these two blogs, so there&#8217;s no need to update your feeds if you&#8217;re too lazy; but if you&#8217;re already subscribing to the Los Techies general feed then you&#8217;ll now get me too.

You can find my blog at: <a href="http://jagregory.lostechies.com">jagregory.lostechies.com</a>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fluent NHibernate usage stats]]></title>
    <link href="http://www.jagregory.com/writings/fluent-nhibernate-usage-stats/"/>
    <updated>2009-03-21T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/fluent-nhibernate-usage-stats</id>
    <content type="html"><![CDATA[Just been totting up some figures on how <a href="http://fluentnhibernate.org">Fluent NHibernate</a> is doing, thought I&#8217;d share them with anyone that&#8217;s interested.

<blockquote>These are very rough figures, generated with no scientific consistency, some are cumulative and others are based just on the last full month. They&#8217;re more just to satisfy my curiosity than to be rigorously accurate.</blockquote>

<table>
  <tr>
    <td>Downloads</td>
    <td>1,800 per month</td>
  </tr>
  <tr>
    <td>Unique visitors</td>
    <td>5,500 per month</td>
  </tr>
  <tr>
    <td>Page views</td>
    <td>13,000 per month</td>
  </tr>
  <tr>
    <td>Mailing list messages</td>
    <td>450 per month</td>
  <tr>
    <td>Commits</td>
    <td>45 per month</td>
  </tr>
</table>

Something else that&#8217;s interesting is of those 5,500 visitors/13,000 page views, 66% are coming directly from google, 4% directly, then the other 30% from referrers. Those referrers are broken down into (from highest to lowest): <a href="http://stackoverflow.com">Stack Overflow</a>, <a href="http://blog.jagregory.com">my blog</a>, <a href="http://pnpguidance.net">pnpguidance.net</a>, <a href="http://nhforge.org">nhforge</a>, then quite a few other sites forming the lower percentages. I&#8217;m surprised at how high Stack Overflow is, I guess it pays that I pay attention to questions asked about Fluent on there.

Those download numbers are probably not representative either as they&#8217;re only of the zip files, while I believe the vast majority of people run off the trunk through Subversion, so it&#8217;s hard to count them.
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Docu + 2 days]]></title>
    <link href="http://www.jagregory.com/writings/docu-2-days/"/>
    <updated>2009-03-21T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/docu-2-days</id>
    <content type="html"><![CDATA[<p>It&#8217;s been two days since I <a href="http://www.jagregory.com/writings/introducing-docu-simple-doc-gen-for-net/">announced</a> <a href="http://docu.jagregory.com">docu</a>, my simple documentation generator for .Net apps.</p>

<p>The reception it&#8217;s received has been positive, I never expected it to have a surge of popularity because it&#8217;s not that kind of tool, so it hasn&#8217;t come as much of a surprise that people haven&#8217;t been jumping all over it. Having said that though, I have had some good feedback and already someone has contributed a patch. Additionally, there hasn&#8217;t been one question as to why I&#8217;ve created it; now this has come as a surprise, I guess I&#8217;m <strong>not</strong> the only one that feels Sandcastle is bloated and overcomplicated. Yay!</p>

<p>I&#8217;ve just pushed out some changes to the <a href="http://github.com/jagregory/docu">github repos</a> and released an updated alpha (v0.1.0.2) on the <a href="http://docu.jagregory.com/downloads">downloads page</a>. The biggest changes so far are the inclusion of events and fields in the parsing, which now means docu has <code>&lt;summary /&gt;</code> support for all documentable members. The rest of the changes are mainly refactorings and some battle-hardening.</p>

<p>I&#8217;ve got some more changes and several issues lined up, so keep an eye out.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Introducing Docu - Simple doc gen for .Net]]></title>
    <link href="http://www.jagregory.com/writings/introducing-docu-simple-doc-gen-for-net/"/>
    <updated>2009-03-19T00:00:00+11:00</updated>
    <id>http://www.jagregory.com/writings/introducing-docu-simple-doc-gen-for-net</id>
    <content type="html"><![CDATA[<p>Lets look at a recent Twitter conversation of mine:</p>

<ul>
<li>Anyone have any tips on generating html docs from XML comments? Used to do it years ago with NDoc <a href='http://twitter.com/jagregory/status/1312895270'>?</a></li>

<li>Man, sandcastle is so overly complex <a href='http://twitter.com/jagregory/status/1313079815'>?</a></li>

<li>Sandcastle examples don&#8217;t even work. This is shit. <a href='http://twitter.com/jagregory/status/1313167377'>?</a></li>

<li>Why isn&#8217;t sandcastle just a console app that takes a list of dlls and spits out html/chm? What&#8217;s with all the batch files and XslTransforms? <a href='http://twitter.com/jagregory/status/1313112789'>?</a></li>

<li>@AndrewNStewart Well Sandcastle requires chaining together several calls to 3+ applications before you get anything. <a href='http://twitter.com/jagregory/status/1315443964'>?</a></li>

<li>Are these Sandcastle generated MSDN-style API docs actually useful to anyone? <a href='http://twitter.com/jagregory/status/1315364767'>?</a></li>

<li>@pollingj It&#8217;s a dilemma. I don&#8217;t care about API docs, but people seem to want it, but I&#8217;m reluctant to generate msdn-like shit. Dilemma. <a href='http://twitter.com/jagregory/status/1315455082'>?</a></li>
</ul>

<p>So as you can see, dilemma. People want API documentation (for <a href='http://fluentnhibernate.org'>Fluent NHibernate</a> specifically), but I don&#8217;t want to associate myself with the awful MSDN-style documentation that&#8217;s produced by Sandcastle.</p>

<blockquote>
<p>Before you get all hot under the collar, if you like Sandcastle, or you like MSDN-style documentation, leave now. Use what works for you, it doesn&#8217;t work for me so I&#8217;m not using it, but I don&#8217;t want to stop you using it.</p>

<p>I realise the market for this tool is probably pretty small, but it&#8217;s useful to me so it might be useful to you.</p>
</blockquote>

<p>Introducing <a href='http://docu.jagregory.com'>docu</a>, the simple documentation generator for .Net!</p>

<p>Docu is a tool that produces an html site (or rather, a collection of html pages) from the doc-comments you include in your code. Given an assembly and the Visual Studio produced XML of the comments, docu will produce a completely static collection of pages that you can publish anywhere you like. You run it through one command-line tool, with one parameter. That&#8217;s it, nothing complicated.</p>

<p><code style="background: #CCC;color: #000;padding: 2px;">docu your-assembly.dll</code></p>

<p>You can see an example of the default style that&#8217;s provided in the Fluent NHibernate <a href='http://fluentnhibernate.org/api/index.htm'>API docs</a> (the colour scheme has been modified, but everything else is default).</p>

<p>Docu is completely stand alone, no GAC deployed assemblies, no hard-coded paths, no nothing. This makes it trivial to use docu in your CI process for building up-to-the-second API docs for publishing or downloading.</p>

<p>The templates that docu uses are created with the <a href='http://sparkviewengine.com'>Spark view engine</a> which means you have all the power of C# and it&#8217;s templating language at your finger-tips. If you&#8217;re particularly picky about appearance (like I am) then you can completely rewrite the templates to your heart&#8217;s content. There&#8217;s no imposed structure or style, it&#8217;s all customisable through the templates. You can read more about customising templates on the site: <a href='http://docu.jagregory.com/customising-templates'>customising templates</a>.</p>

<p>An interesting little feature of the templating system is <em>special names</em> for directories and files, for example if you name a template <code>!namespace.spark</code>, a html page will be produced for a each namespace in your assembly using that template. This allows you to do things like create a directory for each namespace, with a page for each type in that namespace inside. Pretty powerful!</p>

<p>The codebase is reasonably well structured, but the code itself is a bit untidy. Luckily it&#8217;s covered by nearly 200 unit tests (so far) and i&#8217;ll be leveraging them to improve the code quality over time. You can checkout the code from the <a href="http://github.com/jagregory/docu">docu github repo</a>.</p>

<p>It&#8217;s early days yet, there&#8217;s very little customisation of the documentation process (the part that actually finds the types and members to document), and not all comment types are supported yet; however, it&#8217;s used for Fluent NHibernate and works pretty well. It&#8217;s only Alpha right now, so you shouldn&#8217;t expect the world.</p>

<p>So if this kind-of thing interests you, go have a read of the <a href='http://docu.jagregory.com'>docu website</a> and let me know how it works out for you.</p>
]]></content>
  </entry>
  
</feed>
