<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.scottmuc.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Scott Muc]]></title>
  
  <link href="http://scottmuc.github.com/" />
  <updated>2012-01-15T10:22:51-08:00</updated>
  <id>http://scottmuc.github.com/</id>
  <author>
    <name><![CDATA[Scott Muc]]></name>
    <email><![CDATA[scottmuc@gmail.com]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.scottmuc.com/scottmucblog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="scottmucblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title type="html"><![CDATA[Migrated to Octopress!]]></title>
    <link href="http://scottmuc.github.com/migrated-to-octopress/" />
    <updated>2012-01-15T08:45:00-08:00</updated>
    <id>http://scottmuc.github.com/migrated-to-octopress</id>
    <content type="html"><![CDATA[<p>It&#8217;s funny how many posts there are from <a href="https://www.google.com/search?q=migrating+to+octopress">people who have migrated to Octopress</a>. What would motivate someone to post their migration experience? I think I understand why. It&#8217;s such a shift in thinking that it&#8217;s worth talking about. My migration experience was so much pleasant that I feel that I must let everyone know.</p>

<!-- more -->


<p>So what&#8217;s my motivation for moving to a new blogging platform? Was what I was using before broken? Not
exactly, but I didn&#8217;t enjoy the blogging experience that much because I found the experience to not be a
lot of fun. I want to start writing more and feel that removing any barriers to this activity will get more
content out there. I also didn&#8217;t like having to rely on a server side application server. For a website that changes around 30 times a year, a database backed content management system was overkill. Also, the website was hosted on a friends server that I had no backups for, and didn&#8217;t want to spend much effort creating a backup/restoration strategy.</p>

<p>After some searching, I found <a href="http://jekyllrb.com/">jekyll</a>, wich I love for its simplicity. I was going to use bare bones jekyll but then I was directed to <a href="http://octopress.org/">Octopress</a> which is a framework to make working
with jekyll a lot easier.</p>

<p>Since I was on Windows my install was a bit different than the documentation. Luckily I have created a tool
to make <a href="http://scottmuc.com/blog/development/simplifying-ruby-installation-in-windows/">ruby installation simple on Windows</a>. Here&#8217;s everything I did to go from nothing to having a working
blog hosted on github!</p>

<ol>
<li>Installed <a href="https://github.com/scottmuc/yari">yari</a>, and got my environment using ruby 1.9.2</li>
<li>Followed the octopress <a href="http://octopress.org/docs/setup/">setup instructions</a></li>
<li>Followed the octopress <a href="http://octopress.org/docs/deploying/github/">deployment instructions</a></li>
</ol>


<p>I was blown away when I saw my blog appear when I went to <a href="http://scottmuc.github.com/">scottmuc.github.com</a>.</p>

<h3>Migration</h3>

<p>Unfortunately my previous blog engine&#8217;s export functionality is broken so migration had to be manual. Every post
is going to be copy and pasted and re-linkified in markdown syntax. I wanted to get this new version up and
running first so I made a few compromises.</p>

<ol>
<li>I decided not to migrate every post. Some of my old content doesn&#8217;t really fit with the rest of the content
so I decided to abandon the posts. I&#8217;m keeping the <a href="http://old.scottmuc.com/">old blog</a> up and running so that people can still find the posts there if they really want them.</li>
<li>Keeping links working is <strong>extremely</strong> important to me. Octopress provides the ability to set the permalink on
an individual post which made this element of the migration super easy. Every blog post has &#8220;front matter&#8221; which is a little bit of YAML meta data. Adding a permalink value will make the post accessible from that URL path: <pre>permalink: /foo/bar/post</pre></li>
<li>I went live with an incomplete migration. I only have about a third of my posts migrated. I did this so I can
get this live and sort out issues right away before everything is migrated. Also, it&#8217;s a way to motivate me to get
everything into the new blog ASAP.</li>
<li>Added a custom <a href="http://scottmuc.com/non-existent-page/">404</a> to guide those who want to see non-migrated content to the old blog.</li>
<li>Added &#8220;scottmuc.com&#8221; to my CNAME file. I followed the instructions <a href="https://github.com/blog/315-cname-support-for-github-pages">here</a>. Note that this is enabled for non-paying users now! I use <a href="http://gandi.net/">gandi.net</a> for my DNS and updating the A record and CNAME (for www) was a snap.</li>
</ol>


<h3>Other Stuff</h3>

<p>When setting up the blog I had an online discussion about how url design. I decided to leave dates out of my url
and to include them in the title slug only when appropriate. I came to the conclusion that url slug design is
extremely important and doesn&#8217;t always have to be word for word related to the post title. Because Octopress is
so easy to configure, the configuration setting for this is simply this value in _config.yml:</p>

<pre>permalink: /:title/</pre>


<p>I&#8217;m now using other 3rd party services like feedburner, disqus, and gist.github.com. With all of these things
taken care of for me, authoring a post is a call to <em>rake new_post[&#8220;post title&#8221;]</em>, edit in vim, and preview
using <em>rake preview</em> to view the changes before I deploy them.</p>

<p>The one thing I would like to change is learn how to create a custom theme. It&#8217;s quite common to see a lot of
octopress based blogs use the same default theme that I&#8217;m using now.</p>

<h3>Summary</h3>

<p>Octopress is awesome! I love the workflow for authoring new content. I much prefer markdown over using some
WYSIWIG editor over a web connection. The ability to do everything local means there&#8217;s significantly less
effort for me. I believe Octopress is an excellent example of how an excellent deployment mechanism can shift
how work can be done. If pushing brand new code to production is that easy, it removes the need for complex
server side code.</p>

<p>Lastly, if you would like to see what a raw blog post looks like, take a look <a href="https://github.com/scottmuc/scottmuc.github.com/tree/source/source/_posts">here</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Reflections on 2 Years at ThoughtWorks]]></title>
    <link href="http://scottmuc.github.com/blog/development/reflections-on-2-years-at-thoughtworks/" />
    <updated>2012-01-04T10:24:00-08:00</updated>
    <id>http://scottmuc.github.com/blog/development/reflections-on-2-years-at-thoughtworks</id>
    <content type="html"><![CDATA[<p>I cannot believe I&#8217;ve been at ThoughtWorks for 2 years now! My colleague Aaron Erickson has written an excellent writeup on <a href="http://nomadic-developer.com/2012/01/03/why-thoughtworks/">why (work at) ThoughtWorks</a>. I couldn&#8217;t agree more!</p>

<p>Reading another <a href="http://www.adidav9.blogspot.com/2011/09/letter-that-i-present-day-rose-wish.html">colleague&#8217;s post</a> a while ago inspired me to write a little retrospective of my own. Thanks Rose, you are wise beyond your years!</p>

<!-- more -->


<p>ThoughtWorks has been a place I wanted to work for since I attended <a href="http://geekswithblogs.net/mucman/category/6627.aspx">DevTeach in 2007</a>. I met some really smart people who were excellent at articulating their perspective. Also, I observed many of the best blogs I read at the time were written by ThoughtWorkers. Yeah, I was also a BFF (Biggest <a href="http://martinfowler.com/">Fowler</a> Fan), but now my experience has shown me that there&#8217;s so much more.</p>

<p>So far I have worked on 3 large projects. This scale of work wasn&#8217;t exactly what I was expecting to do when I joined. I&#8217;m now thankful I got to work on them because they&#8217;ve all provide unique experiences.</p>

<ul>
<li><strong>Project 1</strong> - This was a pretty hostile environment where I learned how ThoughtWorkers band together and deliver.</li>
<li><strong>Project 2</strong> - I worked on this one for over a year on the largest project at the time. Here I met <a href="http://igiveada.mn/andy-d/">my sponsor</a> (here&#8217;s him in a <a href="http://www.youtube.com/watch?v=A98Asrs0X0g&amp;feature=youtu.be">monkey suit</a> at the ThoughtWorks North America Away Day)who has become an awesome friend in a very short time. The work done there will inspire me for quite a long time. It&#8217;s the reason why I yap about PowerShell so much.
Project 3 - This project was even larger than the previous one. Over 400 people distributed across the globe. Here I learned how to be patient, consistent, understanding, and observant. Large systems have so many variables that coming in complaining and pointing out the flaws gets you nowhere. For 8 months we chipped away and I think we made a difference. It wasn&#8217;t the most interesting project from a technical standpoint. I don&#8217;t think I&#8217;m mature enough yet to understand all the I&#8217;ve learned during this time. Plus I got to work with <a href="https://twitter.com/#!/manderbabble">@manderbabble</a>!</li>
</ul>


<p>Here are some other take-aways from the last 2 years that I did not expect:</p>

<h3>Be Organized</h3>

<p>I&#8217;m pretty organized in general but have realized a lot of people aren&#8217;t. I got the feeling that this ability to be organized help instill confidence in those that depended on what I did. I personally know that it&#8217;s a relief to have people that you can depend on. However, I did feel that I had to nag people on occasion. In large projects there&#8217;s already many different ways to become distracted and I think my organizational skill helped me keep a cool head no matter what kind of perceived chaos was ensuing.</p>

<p>Be awesome to your office manager! He/she runs the joint and when you need that private meeting room, or need lunch ordered for a meeting, they are your go to people. Also figure out logistical tasks like your client email, userid, and network access so soon as you can. Everyone else in the organization will have an expectation on you to have all that stuff sorted out.</p>

<p>Lastly, get a guy (for taxi service). While working in Bellevue I made friends with a father son taxi company (call Harry (206)-724-9525). They reduced the stress of travel big time. I could text them when I needed a lift and they would monitor my travel itinerary and be ready to pick me up at the airport. Their service was absolutely top-notch, thanks Harry and Gill!</p>

<h3>Know Your Org</h3>

<p>Understanding the organizational structure is hugely valuable. As much as we like to complain about how the structure holds you back, that effort is just a waste of energy. Learning the structure and how to use it is key when working with larger organizations. Changing that structure requires lots of time, and the will to build up a lot of trust. This can be, unfortunately, beyond what we can offer as technical consultants.</p>

<p>It&#8217;s funny how often technical help is seeked but the problem is usually human and requires a much different angle to work with. It&#8217;s sad that often I see people try to solve human problems through technical measures. Sometimes it doesn&#8217;t appear to be clear to people that we use computers and work with people, not vice-versa.</p>

<h3>Travel</h3>

<p>For the last 8 months I&#8217;ve been on the road, and I probably only slept in my own bed for about 15 nights in that entire time period (except the Christmas break). This is really fun and exciting (and one of the main draws of ThoughtWorks for me). Here are a few things that it has made me realize:</p>

<ul>
<li>Home is where the laptop is. It&#8217;s amazing how no matter where I traveled to, I would feel quite comfortable as long as I have my laptop and an Internet connection. At all times I&#8217;ve been able to connect with friends and family.</li>
<li>Autonomy is important. No matter where I am, I always try to keep my life autonomous. Some days I would hang out with friends and go with the flow, but many times I would consciencly be sure to break off and do things on my own.</li>
<li>Ok, maybe home isn&#8217;t where the laptop is. Over the holidays I&#8217;ve come to realize that Calgary is truly my home right now. The level of comfort I got from my own bed, couch, diner, and friends was a warm reminder to slow it down every now and then.
I can see how traveling makes it hard for many people to stick with ThoughtWorks. I&#8217;m lucky to be at a point in my life where this amount of chaos is exciting. As much as I enjoyed my week of over the holidays I was ready to get back on the &#8220;road&#8221;.</li>
</ul>


<h3>When You Don&#8217;t Know</h3>

<p>The biggest thing I&#8217;ve learned is how to ask for help. I used to pride myself on being able to do things on my own. Unfortunately I cannot scale, and doing things on my own severely limits my capabilities. Asking for help has been the best thing I&#8217;ve learned. It&#8217;s enabled me to venture into territory that I know little about, but do so without much fear because I know I have awesome colleagues to fall back on.</p>

<p>Even in the personal space I&#8217;ve learned to ask for help. ThoughtWorkers make amazing friends too and provide a support structure that is beyond comprehension. I don&#8217;t know where I would be if it wasn&#8217;t for some of the push and support they&#8217;ve given me.</p>

<p>Saying &#8220;I don&#8217;t know&#8221; amongst a group of ThoughtWorkers is an invitation to be taught without being scoffed at which is better than the snickers and scoffing you get amongst other technical crowds.</p>

<h3>Validation</h3>

<p>This one is a little selfish but working at ThoughtWorks these last couple years have helped me become more confident in my intuition and analysis. Many strategies and tactics I&#8217;ve done earlier on in my career were actually on a correct path, albeit not executed as well because of my naiviety at the time. Before ThoughtWorks I had 8 years of IT work, and I feel even better about the work that I did. Of course I wish I could have done it all differently, but that&#8217;s with todays knowledge.</p>

<p>I now feel even more confident that I can take on problems and solve them even when I really don&#8217;t know exactly what I&#8217;m doing. I&#8217;ve proven to myself that I can solve problems. Hey, if we knew the solutions ahead of time, they wouldn&#8217;t be problems now, would they?</p>

<p>Also like to wish <a href="http://www.codecuriosity.com/">Tyler</a> a happy two years! We started on the same day back in 2010. He&#8217;s managed to put up with my humour longer than any ThoughtWorker and that&#8217;s a pretty good accomplishment.</p>

<p>I&#8217;m now realizing this sounds like a pitch to get people to join ThoughtWorks. It didn&#8217;t start out that way but having more awesome people around doesn&#8217;t sound like such a bad idea! If you&#8217;re interested please check out <a href="http://join.thoughtworks.com/">join.thoughtworks.com</a>.</p>

<p>And now for something completely different (the best image from the last 2 years):</p>

<p><img src="http://scottmuc.github.com/images/blog/bestimageever.jpg"></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[My Developer Resolutions for 2012]]></title>
    <link href="http://scottmuc.github.com/blog/development/my-developer-resolutions-for-2012/" />
    <updated>2011-12-31T10:45:00-08:00</updated>
    <id>http://scottmuc.github.com/blog/development/my-developer-resolutions-for-2012</id>
    <content type="html"><![CDATA[<p>An interesting thing about 2011 is that my resolutions from earlier became quite prominent. Given that 8 months of 2011 were spent on a large account with less technical focus, I&#8217;m amazed at some of the technical things that I&#8217;ve done.</p>

<!-- more -->


<h2>Reflections on 2011 and carry over from 2010:</h2>

<ul>
<li>Mouseless Computing (2010) - I think the practice is paying off as a colleague of mine told me &#8220;You make Windows fly!&#8221;, and he&#8217;s a savvy keyboard only Mac OSX user.</li>
<li>OSS participation (2010) - I started the following projects:

<ul>
<li>Pester - I&#8217;ve blogged about it and it&#8217;s getting some traction out there in the wild. It&#8217;s a spec based testing framework for Powershell. The first implementation was written on a hung-over new years day!</li>
<li>yari - A Windows ruby version manager. Currently being used by a very large client. I wrote this on a whim, because I thought I could do better than what was previously implemented. Turned out the client liked this a lot more and decided to adopt it right away.</li>
<li>YDeliver - The beginnings of a Continuous Delivery framework for .Net projects.</li>
<li>Misc - Submitted a patch to OpenMRS, a bug report to Puppet, directory additions to PSGet</li>
</ul>
</li>
<li>Learn VIM (2011) - This went really well. I&#8217;m definitely no expert at this point but I&#8217;m continuoully trying to learn new things. I&#8217;ve setup a github project for my vimfiles which is a fun way to share my tweaks.</li>
<li>Develop an Android App (2011) - Nope, didn&#8217;t do anything here. It&#8217;s actually dropped off my radar as it&#8217;s not really something I&#8217;m interested in anymore</li>
<li>Learn a server provisioning automation tool (2011) - I barely get a passing grade on this one. I&#8217;ve yet to use any of these tools (chef, puppet, etc&#8230;) on a project. In my spare time I&#8217;ve tried them out and understand the gist of how they work. I do question how necessary they are though. Unless you&#8217;re doing massive scaling it seems like they just add extra overhead for simple scenarios.</li>
<li>Move this blog (2011) - This will be my last post on this blog engine. I&#8217;ve currently setup Octopress and have my new blog ready on github. I just have the task of migrating over all posts (and deleting some). I have more to say about Octopress soon.</li>
</ul>


<h2>Development Goals for 2012:</h2>

<p>2012 is going to be different for me development wise. I&#8217;m finding myself less focused on technical issues and more on system, culture, and people goals. I&#8217;m striving to become more of a leader (clear sign of post-technical syndrome) and I think that&#8217;s reflected in my resolutions for this year.</p>

<h3>Stop reading comments</h3>

<p>Often when I read comments online I want to get those precious minutes of my life back. I favour a discussion over pointless online kibitzing any day. Now of course every scenario is different. The probability of reading comments on Youtube or on some news website is very low. On a blog post about some technical issue, I&#8217;ll likely read the comments.</p>

<h3>No client work when away from client</h3>

<p>Being away from the client is not a place in space problem, it&#8217;s a frame of mind issue. I want to develop some skills in removing myself from the client mentally. This is purely for my own sanity and likely for the sanity of those around me. I&#8217;m finding myself disconnected from my personal goals and more focused at facilitating the goals of whom I am working for. One thing I&#8217;ve learned by being on the road is that ME time is harder to come by. As an introverted individual, that ME time is how I recharge.</p>

<h3>Complete YDeliver</h3>

<p>Hey, an actual technical resolution! By the end of 2012 I want to know that at least 5 projects are using YDeliver. It&#8217;s incomplete right now and I need to get off my arse and complete some of the &#8220;last mile&#8221; stories to get it out there. I also don&#8217;t want to be the single committer to the project. This is a call for help for anyone interested in participating! I have some very strong opinions on how some of the pieces should work together and I will be happy to provide guidance.</p>

<h3>Summary</h3>

<p>Yeah, so this is probably less interesting than previous years. I&#8217;m actually very happy on how my previous resolutions have developed and are continuing to get better and better. In previous years I mentioned developing something on a completely different stack (like Ruby on Rails). Next year I&#8217;m starting a new project working on a small application that involves iOS and ruby development. So work is going to force some of my previous resolutions on me.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Simplifying Ruby Installation in Windows]]></title>
    <link href="http://scottmuc.github.com/blog/development/simplifying-ruby-installation-in-windows/" />
    <updated>2011-11-20T10:54:00-08:00</updated>
    <id>http://scottmuc.github.com/blog/development/simplifying-ruby-installation-in-windows</id>
    <content type="html"><![CDATA[<p>The one thing that has always annoyed me with installing ruby on Windows is that at some point in time I always need to setup the DevKit because I want to install gems that require native extensions. Also, I want the ability to switch between different versions of ruby.</p>

<!-- more -->


<h3>Introducing Yari</h3>

<p>yari is a tool (implemented in Powershell) I&#8217;ve made to simplify both of these operations. Right now it&#8217;s hard coded to only install the 2 ruby versions I care about right now.</p>

<ul>
<li>1.8.7 so I can play with <a href="http://projects.puppetlabs.com/projects/1/wiki/Puppet_Windows">Puppet</a></li>
<li>1.9.2 to be bleeding edge</li>
</ul>


<p><strong>Installation</strong> is described in the readme on the github page. Once installed you can simply run yari from anywhere in the command prompt. Also, you can pass a -InstallMachine argument to yari and it will permanently configure your PATH for the ruby version selected.</p>

<p>So far this tool has made my ruby management in Windows a lot simpler and hopefully it can help you out too. If you find it useful but can use a few changes please submit issues to the projects github page. Or better yet, fork it and submit a pull request.</p>

<p>After installing, here&#8217;s what you&#8217;ll be able to do (and installing things that require native extensions will work):</p>

<pre>
C:\Users\smuc> ruby -v
'ruby' is not recognized as an internal or external command,
operable program or batch file.

C:\user\smuc> yari 1.9.2

C:\user\smuc> ruby -v
ruby 1.9.2p290 (2011-07-09) [i386-mingw32]

C:\user\smuc> yari 1.8.7

C:\user\smuc> ruby -v
ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32]

C:\user\smuc>
</pre>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Madness Must Stop! - PowerShell Package Management]]></title>
    <link href="http://scottmuc.github.com/blog/development/the-madness-must-stop-powershell-package-management/" />
    <updated>2011-10-10T10:57:00-07:00</updated>
    <id>http://scottmuc.github.com/blog/development/the-madness-must-stop-powershell-package-management</id>
    <content type="html"><![CDATA[<p>As a publisher for a few Powershell modules I&#8217;m getting frustrated by the lack of standarization in the community on how to support versioning, deployment and conventions within Powershell module distribution. All I can find is rather adhoc mechanisms of sharing poorly written code with the &#8220;use at your own risk&#8221; kinds of disclaimers.</p>

<!-- more -->


<p>I keep on looking at the ruby community with their amazing tools like rvm, ruby gems, and bundler to make ruby scripting highly testable and repeatable. The formalization also means that you don&#8217;t see people writing ruby code with random imports and magical includes that only work in very specific scenarios. By creating a community around gems and some basic standards, it&#8217;s forced developers to factor their ruby code accordingly and modularize when necessary.</p>

<p>So far I&#8217;ve found the following package management tools for Windows:</p>

<ul>
<li>Nuget - conversations online have lead me to understand that nuget isn&#8217;t meant for powershell</li>
<li>OpenWrap - still under evaluation</li>
<li>Chocolatey (by Rob Reynolds) - wrapper around nuget. Seems to be about config management like Puppet and Chef.</li>
<li>Chewie (by Eric Ridgeway) - bundler for nuget. Could have some input on how to manage PS module packages. Potential to be the front end for managing suites of modules.</li>
<li>Web Platform Installer - not even going to go there</li>
<li>PS-Get (by Andrew Nurse) - built around nuget but Andrew has the MS connection to make it popular.</li>
<li>PS-Get (by Mike Chaliy) - my favourite but needs some growth in the community. A showcase for simplest thing that can possibly work.</li>
<li>Nugit - almost forgot about this late entry. Don&#8217;t know anything about it yet.</li>
</ul>


<p>Here&#8217;s my wishlist (that none of the above can fulfill):</p>

<ul>
<li>Ability to deploy multiple versions of the same package</li>
<li>Different levels of isolation (System | Profile | Project ) levels</li>
<li>A management tool so that projects can declare versions and packages that they need along with dependency chaining (ala bundler and ivy)</li>
<li>Packages can be stored in many different locations (Nuget.org, github, some url pattern)</li>
</ul>


<p>History has shown that pretty much all languages need their own package management system (which can then be wrapped by a system level package manager). I vote that some of us in the community have a round-table and discuss how to move forward with this. There&#8217;s so much to learn from what already exists to get Windows out of the scripting ghetto.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PowerShell BDD Testing - Pester Screencast]]></title>
    <link href="http://scottmuc.github.com/blog/development/powershell-bdd-testing-pester-screencast/" />
    <updated>2011-08-25T11:16:00-07:00</updated>
    <id>http://scottmuc.github.com/blog/development/powershell-bdd-testing-pester-screencast</id>
    <content type="html"><![CDATA[<p>A few months ago I posted a simple tutorial on how to use <a href="http://scottmuc.com/blog/development/pester-bdd-for-the-system-administrator/">Pester (a powershell bdd testing framework)</a>. I&#8217;m starting to practice the making of screencasts so I thought I would add some audio/visual to the blog post. I start rambling in the last 5 minutes so I won&#8217;t feel insulted if you stop paying attention after that part.</p>

<!-- more -->


<p>Also, I want to thank <a href="https://github.com/manojlds">Manoj Mahalingam</a> and <a href="http://blog.martin.aatmaa.net/">Martin Aatmaa</a> for their feedback and contributions!</p>

<p>* <em>the video starts off pixelated but it fixes itself in a few seconds</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Adopting PsGet for PowerShell Module Management]]></title>
    <link href="http://scottmuc.github.com/blog/development/adopting-psget-for-powershell-module-management/" />
    <updated>2011-08-03T11:18:00-07:00</updated>
    <id>http://scottmuc.github.com/blog/development/adopting-psget-for-powershell-module-management</id>
    <content type="html"><![CDATA[<p>For a while now I&#8217;ve been waiting for something that can be as close to ruby gems as possible for PowerShell. For a while I thought Nuget was the way but it&#8217;s tight coupling to Visual Studio made it feel like it wasn&#8217;t quite the right fit for PowerShell.</p>

<!-- more -->


<p>Mike Chaliy has made probably what could be called the simplest thing that could possibly work, and it works well! It&#8217;s called PsGet (not to be confused with another project called PsGet). Take a look at the homepage and bask in its simplicity! Installation is copying/pasting the bootstrap code. Then install modules via name or absolute url to a powershell module.</p>

<p>Take a look at my post about Pester for an example of setting it up.</p>

<p>I have a couple features that I would like to bake into it. Hopefully I won&#8217;t add too much complexity to it as I do really appreciate it&#8217;s simple approach.</p>

<ul>
<li>Ability to deploy a specific version (using git tags) eg: https://github.com/scottmuc/Pester/archives/1.0.3</li>
<li>Something similar to the concept of gemsets in rvm for easy switching between module versions</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Pester - PowerShell BDD Style Testing For The System Administrator]]></title>
    <link href="http://scottmuc.github.com/blog/development/pester-bdd-for-the-system-administrator/" />
    <updated>2011-05-11T20:05:00-07:00</updated>
    <id>http://scottmuc.github.com/blog/development/pester-powershell-bdd-style-testing-for-the-system-administrator</id>
    <content type="html"><![CDATA[<p>Hi there and welcome to my demo of Pester, a BDD style testing framework for Powershell. The creation of Pester came out of the desire to test some build/deployment infrastructure we were creating for a project. We wrote nearly all the code without tests and it came to bite us in the end. I wanted to find a way ensure these problems didn&#8217;t happen again as well as provide some code coverage to give new entrants to the codebase some confidence that they won&#8217;t break everything.</p>

<!-- more -->


<p>Inside Pester there&#8217;s already a trivial Calculator example but it&#8217;s not really the best way to demonstrate the app. Pester itself is tested using Pester. In fact it&#8217;s being tested by the version of Pester that&#8217;s under test (although Martin pointed out some uncovered areas). Still, probably not the best way to show how it all works.</p>

<p>What I&#8217;m going to go through here is the beginning of what could possibly be a real world scenario for a person assigned to write deployment code.</p>

<h2>Here&#8217;s the story:</h2>

<p>Initech has had issues where their .Net web applications have been deployed on production servers with the debug compilation flag set to true. This has made production support people irritable because they now manually tweak the web.config every single time they do a deploy. Michael Bolton has decided he&#8217;s going to automate this step but wants to right it test first. He doesn&#8217;t want to repeat the debacle of his previous attempt at being clever.</p>

<p>First step is to setup a project. Mike (as he now likes be known as) decides to call his project of tools IDeploy and creates a folder of that name where he does is development.</p>

<p>Setting up Pester is simply a matter of following the instructions at PsGet (author Mike Chaliy has tons of great PowerShell modules)then running Install-Pester. Then running Import-Module Pester anytime you open up a PowerShell session where you want to use Pester. The console should look like the following:</p>

<pre>
� MIKE-PC {C:\d\IDeploy} (new-object Net.WebClient).DownloadString("http://bit.ly/GetPsGet") | iex
Downloading PsGet from https://github.com/chaliy/psget/raw/master/PsGet/PsGet.psm1
PsGet is installed and ready to use
USAGE:
    import-module PsGet
    install-module https://github.com/chaliy/psurl/raw/master/PsUrl/PsUrl.psm1

For more details:
    get-help install-module
Or visit http://psget.net
� MIKE-PC {C:\d\IDeploy} import-module PsGet
� MIKE-PC {C:\d\IDeploy} install-module Pester
Module Pester was successfully installed.
� MIKE-PC {C:\d\IDeploy} import-module Pester
� MIKE-PC {C:\d\IDeploy} Get-Module

ModuleType Name                      ExportedCommands
---------- ----                      ----------------
Script     PsGet                     {Get-PsGetModuleInfo, Install-Module}
Script     Pester                    {It, Describe, New-Fixture, Invoke-Pester...}

</pre>


<p>Pester includes a helper function called Create-Fixture. Calling the function with no args looks like the following:</p>

<pre>
� MIKE-PC {C:\d\IDeploy} Create-Fixture
invalid usage, please specify (path, name)
eg: .\Create-Fixture -Path Foo -Name Bar
creates .\Foo\Bar.ps1 and .\Foo.Bar.Tests.ps1
</pre>


<p>Create-Fixture wants to know what the path of your function is going to be and what to call it. I personally like having my tests next to what I&#8217;m testing so Create-Fixture sort of enforces this convention. Note that Pester can be used without ever using this function. I just never remember how to create my fixtures so this saves me a bit of copying and pasting.</p>

<p>Armed with a quick way to create fixtures Michael runs his Create-Fixture to scaffold his feature. He decides he wants it to be called Ensure-AspNetDebugIsFalse and places it in the Deploy\Functions directory of his project.</p>

<pre>
� MIKE-PC {C:\d\IDeploy} Create-Fixture Deploy\Functions Ensure-AspNetDebugIsFalse
Creating => Deploy\Functions\Ensure-AspNetDebugIsFalse.ps1
Creating => Deploy\Functions\Ensure-AspNetDebugIsFalse.Tests.ps1
</pre>


<p>Wanting to see some red he runs the tests by running Invoke-Pester which loads all files that match *.Tests.ps1 recursively in the current directory.</p>

<pre>
� SMUCS-PC {C:\d\IDeploy} Invoke-Pester
Executing all tests in C:\dev\IDeploy\Deploy
Describing Ensure-AspNetDebugIsFalse
does something useful
Tests completed
Passed: 0 Failed: 1
</pre>


<p>As you can see Pester by default makes a failing test. Now it&#8217;s time for Michael to update the test to make it more meaningful. Here&#8217;s his test file after he&#8217;s setup his expectations.</p>

<p>Wow, it failed! Why is that? By default Pester will generate a fixture that is silly and won&#8217;t ever pass. So what should we do with this broken function? As it stands now it&#8217;s totally empty. Let&#8217;s update our specification (aka Test) and do something useful.</p>

<p>So Michael has written a test that didn&#8217;t require a lot of code, but is actually doing a few cool things. I&#8217;ll try to go line by line and explain what&#8217;s going on:</p>

<p>Ensure-AspNetDebugIsFalse.Tests.ps1 contents:</p>

<pre>
$pwd = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
. "$pwd\$sut"
. "$pwd\..\..\Pester.1.0.1\tools\Pester.ps1"
 
Describe "Ensure-AspNetDebugIsFalse" {
 
    Setup -File "inetpub\wwwroot\testsite\web.config" `
                "&lt;configuration&gt;&lt;system.web&gt;&lt;compilation debug='true' /&gt;&lt;/system.web&gt;&lt;/configuration&gt;"
 
    It "switches debug attribute to false for a web.config in a given website path" {
        Ensure-AspNetDebugIsFalse "$TestDrive\inetpub\wwwroot\testsite"
 
        [xml] $xml = Get-Content "$TestDrive\inetpub\wwwroot\testsite\web.config"
        $xml.configuration."system.web".compilation.debug.should.be("false")
    }
}
</pre>


<p>Ensure-AspNetDebugIsFalse.ps1 contents:</p>

<pre><code>function Ensure-AspNetDebugIsFalse($websitePath) {

}
</code></pre>

<p>Here are some details on some of the lines in the test.</p>

<ol>
<li><p>We obtain the directory of the test script because we need to base all other paths off of it</p></li>
<li><p>Here&#8217;s how we ensure our code/test conventions. This means that the code in Foo.Tests.ps1 will automatically include Foo.ps1 (the code under test) in line 3</p></li>
<li><p>Create-Fixture automagically resolves the Pester path no matter what version of Pester you have. This directory will remain static. I might implement an Upgrade-Fixture script so that as you update your Pester version you can update your tests as well.</p></li>
<li><p>Pester has the ability to do filesystem based setups. This line is creating a file in isolation in what Pester calls the $TestDrive. The $TestDrive is disposed of after every Describe context. This allows you to perform filesystem related tasks without having to maintain separate test files. This line has created a file called web.config in the inetpub\wwwroot\testsite path in the $TestDrive and the 2nd argument is the content of that file.</p></li>
<li><p>We execute the code we want to test</p></li>
<li><p>We assert that the debug attribute has been set to false.</p></li>
</ol>


<p>Let&#8217;s make this bad boy pass!
Here&#8217;s the function fleshed out and the test passes!</p>

<pre>
function Ensure-AspNetDebugIsFalse($websitePath) {
    $webConfigPath = "$websitePath\web.config"
 
    [xml] $webConfig = Get-Content $webConfigPath
    $webConfig.configuration."system.web".compilation.debug = "false"
    $webConfig.Save($webConfigPath)
}
</pre>


<p>and the execution of the test:</p>

<pre>
� MIKE-PC {C:\d\IDeploy} Invoke-Pester
Executing all tests in C:\dev\IDeploy\Deploy
Describing Ensure-AspNetDebugIsFalse
switches debug attribute to false for a web.config in a given website path
Tests completed
Passed: 1 Failed: 0
</pre>


<p>Now Michael has an extra tool at his disposal to call when he&#8217;s performing deployments. If only he had taken this approach when he wrote his money transfer code. He wouldn&#8217;t have missed all those decimal places!</p>

<p>Hope this helps get you running with Pester. There&#8217;s a lot more I would like to add but I&#8217;m really only adding stuff as I see the need for it. Pester was driven out by my desire to refactor another Powershell library I wrote called PowerYaml. Take a look at the project page to see how I took the untested code, wrapped tests around it, then refactored.</p>

<p>Feedback is greatly appreciate and I hope this helps your teams make reliable Powershell scripts.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Stop Trying to be Perfect and Make Mistakes!]]></title>
    <link href="http://scottmuc.github.com/blog/development/stop-trying-to-be-perfect-and-make-mistakes/" />
    <updated>2011-01-30T21:30:00-08:00</updated>
    <id>http://scottmuc.github.com/blog/development/stop-trying-to-be-perfect-and-make-mistakes</id>
    <content type="html"><![CDATA[<p>Think about how you get good at anything. What do you remember spending most of your time on? Most likely you spent the majority of your time messing things up and getting it wrong. Why are kids so quick at picking up new skills, especially dangerous ones? It&#8217;s because kids are fearless experimenters. I&#8217;m currently learning how to skate and ski and my ability to learn is hindered by my concern of hurting myself; potentially preventing me from working and earning a living. I want to try and correlate the idea of failure as a healthy activity in the road to expertise in the world of operations in the software world.</p>

<!-- more -->


<p>Operations people have two numbers they care about. The number 9 and how many of them they have (99.999% uptime is commonly known as five nines). This is a great metric for a system that doesn&#8217;t change, but in a world where new requirements are constantly conjured up and need to be live yesterday, the number of 9&#8217;s you have becomes harder to keep stable. A new operational metric needs to be created to handle this new kind of ever changing system.</p>

<p>Historically operations people are stereotyped as grumpy curmudgeons who will only let you deploy something in the 1 minute downtime window that they provide for you on the 3rd full moon after each solstice on a Sunday night at 2:29am, and you better get it done before the backups fire up or else you&#8217;re screwed! Developers on the other hand are eager to get their newly written code live so that people can see the fruits of their labour. It&#8217;s pretty obvious that these mentalities are in complete opposition.</p>

<p>This clash of values can be lessened if operators adopted a new bragging metric. The <strong>Mean Time to Recovery (MTTR)</strong>. An operations person that can fix a problem fast is much stronger than someone without that kind of debugging ability. To get ops to fix problems that means they need to have strong knowledge of the applications they are deploying and strong relationships with the teams that developed them. The hard part about this metric is that it needs to be exercised. You can&#8217;t measure your MTTR unless things break.</p>

<p>Another great metric was created by the Lean way of thinking where minimization of completed features (an inventory) waiting to go live is important because that backlog is considered wasteful. This is still a great system wide view of shortening the time from concept to market, but I want to focus a little on the mind of an operations person.</p>

<p>One of the problems with software development is a general sense of hubris when it comes to the stability and functionality of an application. Stats like the number of unit tests and code coverage are often leaned on with the implicit understanding that it means the code is working. That&#8217;s when concepts like <a href="http://en.wikipedia.org/wiki/Mutation_testing">Mutation Testing</a> are great for truly determining the value and confidence that the test suite brings. Tools like <a href="http://jester.sourceforge.net/">Jester perform</a> a little bytecode magic behind the scenes to determine how brittle your tests are.</p>

<p>Operations can suffer from the same kind illogical confidence. How are the 9&#8217;s measured? I&#8217;ve often seen uptime measured by how long heartbeat.html is still up, but how confident would that make you believe that the entire system can still process an order? A server that&#8217;s up and running serving up broken software should not count as being &#8220;up&#8221;. This is where a common agreement of the term &#8220;done&#8221; is important in bridging the gap between software development and operations.</p>

<p>It&#8217;s too bad that ops can&#8217;t perform activities like TDD where the developer intentionally fails a test in order to drive out the code to implement a feature.</p>

<p>At a few conferences I&#8217;ve met a few people who deploy to production rapidly in massive systems (<a href="http://engineering.imvu.com/2010/04/09/imvus-approach-to-integrating-quality-assurance-with-continuous-deployment/">IMVU</a>, <a href="http://glinden.blogspot.com/2009/11/continuous-deployment-at-facebook.html">Facebook</a>). They don&#8217;t know 100% the code they are deploying won&#8217;t break in production. By deploying to partitions they can use system wide health metrics to determine whether or not things are working. Are orders still being processed in the partition that the new code was deployed to?</p>

<p>In my previous work experience I deployed code to production all the time (and broke things). Every time I broke something was a learning experience, but I didn&#8217;t stress about it because I knew how to fix things reasonably fast. I didn&#8217;t realize at the time how valuable that was. Periodic failure was welcome because it re-assured us that we knew how the system worked. Now of course mission critical applications have much different sensitivities to failure. I&#8217;m not talking about software that launches the space shuttle here.</p>

<p>In conclusion I would like to see how we can allow operations to fail without such a negative impact. If a deployment fails because someone forgot to chmod a file with +x, that&#8217;s a great lesson learned and hopefully someone will update the deployment script. After all, we&#8217;re all human and we make mistakes. By recording the operational MTTR we can grow a team that updates production frequently and fixes errors fast, rather than a team performs massive batch releases to production and slowly figures out the errors. So let&#8217;s figure out how we can help our ops people fear downtime a bit less and empower them with the ability fix the software we build. On the flip side lets write software that is easily deployable and doesn&#8217;t require pages of instructions to make live so that operations can feel more comfortable tweaking and redeploying with confidence.</p>

<p>I don&#8217;t propose any solutions to this mindset but would love to hear some feedback. Would measuring MTTR be important in an operations group?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[My Developer Resolutions for 2011]]></title>
    <link href="http://scottmuc.github.com/blog/development/my-developer-resolutions-for-2011/" />
    <updated>2010-12-27T21:35:00-08:00</updated>
    <id>http://scottmuc.github.com/blog/development/my-developer-resolutions-for-2011</id>
    <content type="html"><![CDATA[<p>Looking back at 2010 I can&#8217;t say I did a good job of following through with <a href="http://scottmuc.com/blog/development/my-developer-resolutions-for-2010/">my resolutions</a>, but I believe I have a valid excuse! For the last 12 months I&#8217;ve been working more as a <a href="http://scottmuc.com/blog/development/getting-my-build-and-release-on/">build/release specialist</a> than a software developer. Anyways, here&#8217;s a rundown of what I didn&#8217;t accomplish last year:</p>

<!-- more -->


<ul>
<li>Test Driven Design - I barely coded at all so that was a total flop. I also believe that this is something that&#8217;s hard to do on your own. This discipline really needs a pair in order to stay on track.</li>
<li>Mouseless Computing - This is probably my most successful resolution. I&#8217;m still no keyboard ninja, but I&#8217;ve improved over last year and even wrote a fun negative re-inforcement application.</li>
<li>OSS Participation - I&#8217;m going to defer this to this year as I have a couple things planned for the near future.</li>
<li>Complete small project in different dev stack - Total flop. I attempted to do something in Rails and I couldn&#8217;t get going. I think I&#8217;ve been in the .Net world for too long. New frameworks completely twist the way I do things and I find I&#8217;m not good at learning the conventions of these new technologies.</li>
</ul>


<h2>Development Goals for 2011:</h2>

<h3>Learn VIM (building my lightsaber)</h3>

<p>I&#8217;ve tried to find the perfect editor for ages. I&#8217;ve sort of come to the conclusion that I&#8217;m going to be a perpetual generalist. Sometimes I find myself working on all sorts of OS&#8217;s (Ubuntu, Win7, Mac OSX), and I don&#8217;t want to learn the best editor for each (GEdit, Notepad++, TextMate). VIM works on all of them so why not learn that? Historically VIM has been labelled as a difficult but powerful editor and with good reason. I&#8217;m writing this post in VIM and discovering how much learning I have to do to get to the level of VIM experts.</p>

<p>To make it more fun I&#8217;m treating VIM like a lightsaber. It&#8217;s the weapon that every Jedi must construct themselves. Part of the lightsaber is the crystal which is imbued with the force and resonates to produce the blade. To me, the .vimrc file is my version of my set of lightsaber crystals. Hopefully with some study and careful construction (and vimcasts) I can craft my very own coding lightsaber.</p>

<h3>Develop an Android App</h3>

<p>I&#8217;ve always wanted to dive into the mobile development world but I don&#8217;t own a Mac so iOS was out. Windows mobile development didn&#8217;t seem that much fun, and Blackberry was definitely out of the question. PalmOS was too niche as well so I passed on that too.</p>

<p>Now that I have an Android based phone and I have an idea for an application (using SongKick), my goal is to release something to the Android market sometime this year. At the same time I want to play around with Ubuntu as my development environment while I&#8217;m at it.</p>

<h3>Learn a server provisioning automation tool</h3>

<p>This year I learned about the term DevOps, and sort of got to work under that kind of role. I didn&#8217;t do such a great job of it as I&#8217;m more a dev than I am an ops, but I want to change that. Tools like Chef, Puppet, Babushka, Vagrant all look really interesting and I would like see how I can use these tools to solve some interesting problems. Unfortunately I can&#8217;t put them in my problem solving toolkit until I actually know how to use them.</p>

<p>Along with these tools, I&#8217;ll probably train myself on VM technologies so I can re-provision servers and play around with these automation tools.</p>

<h3>Move this blog</h3>

<p>At some point this year I need to get this blog off of this application. This old version of Graffiti CMS uses VistaDB for it&#8217;s persistent datastore and the BlogML export functionality is broken.</p>

<p>That&#8217;s it! Hopefully I&#8217;ve kept the scope small enough that I can actually accomplish all of this. It&#8217;s strange looking at my resolution posts and realizing how little I achieve of the small goals that I set for myself. Just goes to show how fast a year goes by and how your experiences can be steered in so many directions along the way.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Book Review - The Art of Unit Testing by Roy Osherove]]></title>
    <link href="http://scottmuc.github.com/blog/reviews/book-review-the-art-of-unit-testing-by-roy-osherove/" />
    <updated>2009-07-08T08:56:00-07:00</updated>
    <id>http://scottmuc.github.com/blog/reviews/book-review-the-art-of-unit-testing-by-roy-osherove</id>
    <content type="html"><![CDATA[<p><img class="left" src="http://www.manning.com/osherove/osherove_cover150.jpg">
In a recent splurge I purchased 4 books from <a href="http://www.manning.com/">Manning Press</a> with one of them being <a href="http://www.manning.com/osherove/">The Art of Unit Testing</a> by <strong>Roy Osherove</strong>.</p>

<p>I would categorize myself as relatively new to unit testing. My first hands on testing was when I took the Nothing but .Net bootcamp with JP Boodhoo but he emphasized BDD style tests. I saw the benefit of BDD but didn&#8217;t feel I had the know how to implement them properly. About 3 months ago I started writing tests in a more unit test like fashion and things started clicking.</p>

<!-- more -->


<p>This book felt like an Assertion of what I&#8217;ve learned over the last year. As I read the book I kept finding stories I could relate to. In my attempts to apply unit testing to my own code, I experienced nearly everything Roy talks about in this book.</p>

<p><strong>Chapter 5</strong> was great a explaining the differences between the terms <a href="http://www.martinfowler.com/articles/mocksArentStubs.html">Stub and Mock</a>. What I liked was how he provided samples of manual stubs and mocks to give the reader a peak under the curtain as to what a mock (err faking, Roy&#8217;s personal word preference) framework does for us. I can understand how the work mock is overloaded now, and can appreciate the proper terminology and it helps when explaining these concepts to others.</p>

<p>For me <strong>Chapters 6 and 7</strong> are where I got the most out of the book. Through all my reading of testing on-line, I found it quite simple because the scope of the demos were so small. I felt these two chapters armed me with some good principals on organizing tests and treating them just as important as my production code.</p>

<p>All in all this was one of the easiest programming books I&#8217;ve ever read. Roy&#8217;s tone was fun (especially his little jab at <a href="http://ayende.com/">Ayende</a>), but wasn&#8217;t so opinionate that it sounded preachy. In fact I felt comfortable making my own opinions that extend his foundations. Roy presented the material in a way that seems like he assumes you&#8217;re not an idiot. There wasn&#8217;t a lot of &#8220;hand holding&#8221; which can be found in other entry level books. He provides ample resources for those that want more instruction on certain topics which creates a good pace for the reader.</p>

<p>As for the negatives: I wish it was a little longer. I don&#8217;t know why, but I felt that there was more to say on a lot of topics. Perhaps more examples, which could seem a bit repatitive, but could be skipped by those who got the message. I also didn&#8217;t like how <a href="http://typemock.com/">TypeMock</a> was being pushed heavily and the disclaimer that Roy worked for TypeMock didn&#8217;t come in until near the end.</p>

<p>I would reccomend this book to anyone who is new to unit testing. I think I read the book at almost a perfect time. I knew enough that I could see past the trivial example to the message he&#8217;s delivering, but not enough to skip all the material because it was so obvious. A seasoned unit tester might not get as much value from this book, but I would urge them to get it anyways so they can loan it to those they work with who are new to testing.</p>

<p>A great prelude to reading this book is to watch Roy review the test suites for the following projects:</p>

<p><a href="http://weblogs.asp.net/rosherove/archive/2009/03/20/test-review-1-nerddinner.aspx">Nerd Dinner</a> <br />
<a href="http://weblogs.asp.net/rosherove/archive/2009/03/21/test-review-2-asp-net-mvc-unit-tests.aspx">Asp.Net MVC</a> <br />
<a href="http://weblogs.asp.net/rosherove/archive/2009/03/23/test-review-3-unity.aspx">Microsoft Unity</a></p>

<p>Be warned, you&#8217;ll be watching a grumpy Roy at 2am :-). Roy also has a <a href="http://osherove.com/blog">great blog</a> and is active on <a href="http://twitter.com/RoyOsherove">twitter</a> as well.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Riding The Lines-Of-Code Rollercoaster]]></title>
    <link href="http://scottmuc.github.com/blog/development/riding-the-lines-of-code-rollercoaster/" />
    <updated>2009-05-20T08:52:00-07:00</updated>
    <id>http://scottmuc.github.com/blog/development/riding-the-lines-of-code-rollercoaster</id>
    <content type="html"><![CDATA[<p>Lines of code has always been a poor guide in measuring developer productivity. I&#8217;m currently reading <a href="http://en.wikipedia.org/wiki/Scott_Rosenberg_(journalist)">Scott Rosenberg&#8217;s</a> <a href="http://www.dreamingincode.com/">Dreaming In Code</a> and came across and interesting quote.</p>

<blockquote><p>  &#8220;Atkinson [ed: Bill] had just completed rewriting a portion of the Quickdraw code, making it more efficient and faster. The new version was 2000 lines of code shorter than the old one. What to report? He wrote the number -2000&#8221; &#8211; <strong>Rosenberg</strong></p></blockquote>

<p>I couldn&#8217;t help but smile when I read that. I have felt that some of my best coding successes are when I eliminate lots of code. This probably pushes Test Driven Development (TDD) as a great practice even further. Lately I&#8217;ve been a bit stricter by doing TDD. This means that I&#8217;m writing a lot more code, but as I get my tests passing I start refactoring and remove much of the code that&#8217;s written. For every couple hundred lines of code I write, I eventually remove 50-80% of it as I glean knowledge from all the code I previously wrote.</p>

<p>It appears that LOC Rollercoaster development is an artifact of TDD and it&#8217;s a great ride!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Unit Testing Domain Persistence With NDbUnit]]></title>
    <link href="http://scottmuc.github.com/blog/development/unit-testing-domain-persistence-with-ndbunit-nhibernate-and-sqlite/" />
    <updated>2009-03-09T07:51:00-07:00</updated>
    <id>http://scottmuc.github.com/blog/development/unit-testing-domain-persistence-with-ndbunit</id>
    <content type="html"><![CDATA[<p>Ever since I&#8217;ve begun using NHibernate the number one thing that&#8217;s caused me a lot of headaches is learning how to properly map my domain objects. Even the most basic mappings I wrote had bugs simple because I overlooked trivial items. This made me realize that I could save a lot of time and hassle if I unit tested by data access layer.</p>

<p>Ever since I&#8217;ve begun using NHibernate the number one thing that&#8217;s caused me a lot of headaches is learning how to properly map my domain objects. Even the most basic mappings I wrote had bugs simple because I overlooked trivial items. This made me realize that I could save a lot of time and hassle if I unit tested by data access layer.</p>

<!-- more -->


<p>I&#8217;m a neophyte when it comes to unit testing, but over the last six months I&#8217;ve started to understand the benefits of testing and where it fits in with my development cycle. In order to test my mappings I needed a simple way of placing dummy data into my database. I also wanted to use SQLite as my test database implementation for simplicity, and speed reasons. When a new developer jumps on board, I think it would be cool if they can run the database unit test suite without having to setup SQL Server, or any other database application server. My research led me to a project called NDbUnit. It allows a simple way to populate a database with data from an Xml DataSet. This is exactly what I wanted, but it did not support SQLite. I took the plunge and implemented a SQLite provider and even got it added to their codebase! <a href="http://scottmuc.github.com/blog/development/when-1-does-not-equal-1-a-debugging-tale/">I&#8217;ve already blogged</a> about that tangent here.</p>

<p>With tools in hand I started creating an integration test suite for the CBC Radio 3 website codebase. The website is currently undergoing a re-write where I am migrating from my hand written data access layer to an NHibernate based DAL (Data Access Layer). Oh how do I wish I wrote it with NHibernate from the beginning :-). The current database has 92 tables and I&#8217;ve only just begun mapping them to proper Domain objects. So far I&#8217;ve written about 20 Domain objects and I&#8217;ve hit enough walls with the mapping files. I realized that I needed a testing foundation to assert the persistence of my domain objects.</p>

<p>Enough about my objectives, here&#8217;s how I plan on making a database testing suite that doesn&#8217;t get bogged down by the size of the domain or the number of repositories I have.</p>

<p>I&#8217;ve attached an NDbUnit demo code base that should be fully runnable within Visual Studio if you care to try this out for yourself. Note that I&#8217;ve used a lot of thirdparty tools to assist with this setup:</p>

<ul>
<li>Castle.Windsor</li>
<li>Rhino.Commons.Binsor</li>
<li>Castle.Facilities.NHibernateIntegration</li>
<li>NHibernate</li>
</ul>


<p>The first step in setting all this up is my first test which does not have any assertions. It&#8217;s existence is purely to have a simple way of creating the SQLite database file with the schema populated from the Domain.</p>

<div><script src='https://gist.github.com/1551024.js?file=CreateDatabase.cs'></script>
<noscript><pre><code>[Fact(Skip = &quot;Only need this to setup the DB&quot;)]
public void CreateDatabaseSchemaFromMappingFiles() 
{
    IWindsorContainer container = new WindsorContainer()
        .Install(BinsorScript.FromFile(TestConfiguration.BinsorConfig));

    var cfg = container.Resolve&lt;Configuration&gt;();
    var schema = new SchemaExport(cfg);
    schema.Create(true, true);
}</code></pre></noscript></div>


<p>To elaborate briefly, the first line gets the Windsor container from a Boo config file. Next, it obtains the NHibernate Configuration object from the container, then exports the schema. There&#8217;s a lot of magic being done in these few lines of code and I would like to thank all those who worked on these projects for making my life a lot easier. My TestConfiguration class is just a wrapper around some hard coded string:</p>

<div><script src='https://gist.github.com/1551024.js?file=TestConfiguration.cs'></script>
<noscript><pre><code>public class TestConfiguration
{
    public const string BinsorConfig = @&quot;..\..\config\container.boo&quot;;
    public const string ConnectionString = @&quot;Data Source=ndbunitdemo.db;Version=3;New=True&quot;;
}</code></pre></noscript></div>


<p>The test setup is inspired by Chris Canal&#8217;s post on &#8220;Blistering Fast Integration Tests with NHibernate and SQLIte&#8221;. My Boo config files are nearly identical to his, so I&#8217;ll save the bits and not paste them here.</p>

<p>Next I create a RepositoryTestBase to encapsulate the construction of my container and expose the ISessionManager to all my tests.</p>

<div><script src='https://gist.github.com/1551024.js?file=RepositoryTestBase.cs'></script>
<noscript><pre><code>public class RepositoryTestBase : IDisposable
{
    public RepositoryTestBase()
    {
        InitializeContainer();
    }

    private static void InitializeContainer()
    {
        if (IoC.IsInitialized) return;
        
        var container = new WindsorContainer()
            .Install(BinsorScript.FromFile(TestConfiguration.BinsorConfig));

        IoC.Initialize(container);
    }

    protected static ISessionManager SessionManager
    {
        get { return IoC.Resolve&lt;ISessionManager&gt;(); }
    }

    public void Dispose()
    {
        IoC.Reset();
    }
}</code></pre></noscript></div>


<p>So that&#8217;s pretty much all the underlying infrastructure for my database tests so far. Since I have a lot of tables to test, and NDbUnit requires that I model them using Xml DataSet schema definitions I didn&#8217;t want to put them all in one file. I eventually came to the realization that I could segregate my XSD files to contain only the tables that I needed to test certain Aggregate Roots (although I barely know if I&#8217;m using that term correctly). When testing my IArtistRepository, I didn&#8217;t want to have to put Blog tables in my XSD and vice-versa. I eventually came up with a directory structure to deal with separating the concerns of my database tests. Each repository would get its own directory/namespace for all the classes that it&#8217;s concerned with.</p>

<p>I ended up designing the system so I have three repositories that returned a BlogPost, User, and Profile. So in my integration test suite I have directories for { Blog, Profiles, Users } to group repository functionality.</p>

<p>In each repository directory I create a custom test context class as a base class for all other fixtures in the directory. This test context will be used to expose the repository that&#8217;s under test, and to populate the dummy database using NDbUnit. Here&#8217;s an example of the UserRepositoryTestContext</p>

<div><script src='https://gist.github.com/1551024.js?file=UserRepositoryTestContext.cs'></script>
<noscript><pre><code>public class UserRepositoryTestContext : RepositoryTestBase
{
    protected static IUserRepository Repository
    {
        get { return IoC.Resolve&lt;IUserRepository&gt;();  }
    }


    public UserRepositoryTestContext()
    {
        var dbUnitTest = new SqlLiteUnitTest(TestConfiguration.ConnectionString)
                             {
                                 QuotePrefix = &quot;[&quot;,
                                 QuoteSuffix = &quot;]&quot;
                             };

        const string xmlPath = @&quot;..\..\Users\Xml\&quot;;

        dbUnitTest.ReadXmlSchema(Path.Combine(xmlPath, &quot;UsersDS.xsd&quot;));
        dbUnitTest.ReadXml(Path.Combine(xmlPath, &quot;Users.xml&quot;));
        dbUnitTest.PerformDbOperation(DbOperationFlag.CleanInsert);            
    }
}</code></pre></noscript></div>


<p>The XSD for this section contains a dataset that for the Users, Roles, and UserRoles tables and the dummy data looks something like the following:</p>

<p><img src="http://scottmuc.github.com/images/blog/UsersDS.jpg"></p>

<div><script src='https://gist.github.com/1551024.js?file=Users.xml'></script>
<noscript><pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;UsersDS xmlns=&quot;http://tempuri.org/UsersDS.xsd&quot;&gt;
  &lt;Users&gt;
    &lt;Id&gt;1&lt;/Id&gt;
    &lt;Name&gt;User1&lt;/Name&gt;
  &lt;/Users&gt;
  &lt;Users&gt;
    &lt;Id&gt;2&lt;/Id&gt;
    &lt;Name&gt;User2&lt;/Name&gt;
  &lt;/Users&gt;
  &lt;Roles&gt;
    &lt;Id&gt;1&lt;/Id&gt;
    &lt;Name&gt;Admin&lt;/Name&gt;
  &lt;/Roles&gt;
  &lt;Roles&gt;
    &lt;Id&gt;2&lt;/Id&gt;
    &lt;Name&gt;User&lt;/Name&gt;
  &lt;/Roles&gt;
  &lt;UserRoles&gt;
    &lt;UserId&gt;1&lt;/UserId&gt;
    &lt;RoleId&gt;1&lt;/RoleId&gt;
  &lt;/UserRoles&gt;
  &lt;UserRoles&gt;
    &lt;UserId&gt;2&lt;/UserId&gt;
    &lt;RoleId&gt;2&lt;/RoleId&gt;
  &lt;/UserRoles&gt;
&lt;/UsersDS&gt;</code></pre></noscript></div>


<p>Now I can write succinct unit tests leveraging all the infrastructure that I&#8217;ve put in place:</p>

<p>The User domain object is quite simple and that&#8217;s why I also have tests for a simple BlogPost class that has a child collection of Comments. Using a similar structure I can write painless tests like the following:</p>

<div><script src='https://gist.github.com/1551024.js?file=UserPersistenceTests.cs'></script>
<noscript><pre><code>public class UserPersistenceTests : UserRepositoryTestContext
{
    [Fact]
    public void Can_retrieve_user_from_repository()
    {
        using (SessionManager.OpenSession())
        {                
            var user = Repository.GetById(1);
            Assert.Equal(1, user.Id);
        }
    }
}</code></pre></noscript></div>


<p>With this kind of segregation between the repository tests I don&#8217;t have to worry about creating XSD DataSets for my entire database in one file. I can pick and choose the tables I want to test directly using NDbUnit. For my Blog tests, I didn&#8217;t want to worry about User persistence even though it&#8217;s mapped as a property on my BlogPost class. By leveraging lazy loading I don&#8217;t need to worry that I don&#8217;t have a valid User object in the database because my tests never access the User property, therefore I don&#8217;t get any exceptions when the NHibernate generated proxy attempts to obtain that entity from the session/database.</p>

<p>That concludes my one week analysis of using NDbUnit to testing my NHibernate persistence layer. Please leave a comment if you have suggestions on this setup. So far this setup hasn&#8217;t caused me too much grief, but it&#8217;s only been in use for a few days. On the surface it seems clean to me, but take it all with a grain of salt.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[When 1 Does Not Equal 1]]></title>
    <link href="http://scottmuc.github.com/blog/development/when-1-does-not-equal-1-a-debugging-tale/" />
    <updated>2009-02-27T07:41:00-08:00</updated>
    <id>http://scottmuc.github.com/blog/development/when-1-does-not-equal-1</id>
    <content type="html"><![CDATA[<p>I&#8217;m starting to get comfortable with <a href="http://nhforge.org/Default.aspx">NHibernate</a> but I&#8217;ve been <a href="http://en.wikipedia.org/wiki/Cowboy_coding">cowboy coding</a> it without any testing framework to let me know if my mappings are really doing what I think they are doing. I&#8217;m starting to get tired of manually interacting with my applications to see if things work so I&#8217;ve begun the course of starting database integration testing. For the most part, it&#8217;s all about testing my mapping files.</p>

<!-- more -->


<p>Because these tests are meant to be automated, I wanted to be as easy as possible to get the test framework into a consistent state. I found tool called <a href="http://code.google.com/p/ndbunit/">NDbUnit</a> and it allowed me to dump data stored in Xml straight to your database. It was looking great until I found out it didn&#8217;t support <a href="http://www.sqlite.org/">SQLite</a> which is the database engine I want to use for the testing because of speed reasons. At least the tool is extensible and I took some time to write a SQLite portion to the codebase.</p>

<p>Anyways, enough about what lead me to this post. During the development of SQLite integration I came across a weird bug. A feature of NDbUnit is to allow a refresh of the data, so you can merge/update/insert new data without having to completely remove everything from the test database. One of the parts of this code is to compare the data set from the xml file to the data in the database. To find out if an <strong>UPDATE</strong> needs to be done versus and <strong>INSERT</strong> is by the return value of this method:</p>

<pre>
protected bool IsPrimaryKeyValueEqual(DataRow dataRow1, DataRow dataRow2, DataColumn[] primaryKey)
{
    if (primaryKey.Length == 0)
    {
        return false;
    }

    for (int i = 0; i < primaryKey.Length; ++i)
    {
        DataColumn dataColumn = primaryKey[i];
        // Primary key column value is not equal.
        if (!dataRow1[dataColumn.ColumnName].Equals(dataRow2[dataColumn.ColumnName]))
        {
            return false;
        }
    }

    return true;
}
</pre>


<p>It simply goes through all the keys of the table, and if they are all equal, then we&#8217;ve found a tuple that needs to be updated. Seems pretty straightforward, and not a method that I would presume would cause any problems. Strangely enough, here is where some strangeness started to occur. This method would always return false! I hooked up the debugger and inspected the rows and everything seemed normal. Until what seemed like the 30th time; I noticed something. The row from the XML had 32 bit IDs while the row from the SQLite database had 64 bit IDs.</p>

<p><img src="http://scottmuc.github.com/images/blog/debugger_tail_32bit.png" /></p>

<p>and here&#8217;s what that DataRow object was being compared to:</p>

<p><img src="http://scottmuc.github.com/images/blog/debugger_tail_32bit.png" /></p>

<p>I didn&#8217;t want jump to conclusions as to whether or not I found my problem so I wrote a test. Sure enough, the following test fails (and for good reason).</p>

<pre>
[Test]
public void One_should_equal_one()
{
    object _32bit1 = (Int32) 1;
    object _64bit1 = (Int64) 1;

    bool result = _64bit1.Equals(_32bit1);
    
    Assert.IsTrue(result);
}
</pre>


<p>Since SQLite always uses 64 bits for its integers I simply made a copy of the XSD file (which defines how the XML data relates to the database schema) and replaced the xs:int id declarations with xs:long data type.</p>

<p>The End.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[My Developer Resolutions For 2009]]></title>
    <link href="http://scottmuc.github.com/blog/development/my-developer-resolutions-for-2009/" />
    <updated>2008-12-30T00:11:00-08:00</updated>
    <id>http://scottmuc.github.com/blog/development/my-developer-resolutions-for-2009</id>
    <content type="html"><![CDATA[<p>I&#8217;ve never made any New Years resolutions before. This year I&#8217;m going to break that trend simply to create a checklist of tasks to keep me on track. I easily get distracted, but having to check things off a list is a sure way for me to stay focused.</p>

<p>Not wanting to over do it, I made goals that are easily attainable. Hopefully upon completion I&#8217;ll get more ambitious the next time around.</p>

<!-- more -->


<h3>Development Goals:</h3>

<p>Lately I&#8217;ve been spending a lot of time thinking about &#8220;the build&#8221;. Strangely enough, I get a lot of satisfaction out of a useful build environment. When I can checkout some code and be able to build and run a local instance of an application with a single command line execution, I feel great sense of value from the work put into my build scripts. These thoughts have heavily influenced my technical aspirations for 2009.</p>

<h4>Learn A New Build System</h4>

<p>I Love <a href="http://nant.sourceforge.net/">NAnt</a>, but I&#8217;m really starting to hate XML. It&#8217;s not that I want to ditch NAnt because I know it well, and it does the job. It&#8217;s just that I think it&#8217;s could practice to see how the same thing can be done in other ways.</p>

<ul>
<li><span style="text-decoration: line-through;">Boobs</span> <a href="http://code.google.com/p/boo-build-system/">Bake</a> - Written by the great <a href="http://ayende.com/">Ayende</a> and uses the Boo language as its syntax.</li>
<li><a href="https://github.com/JamesKovacs/psake">PSake</a> - Written by <a href="http://jameskovacs.com/">James Kovacs</a> and is written in PowerShell. I&#8217;ve yet to get into PowerShell and a build system seems like a natural place to start learning it. The one downside is that I don&#8217;t believe it&#8217;ll work in a Linux environment (or any environment without PowerShell for that matter).</li>
<li><a href="http://rake.rubyforge.org/">Rake</a> - Ruby is another language I would like to learn and build scripts is yet another applicable task for it. Rake has a fairly large user base and it&#8217;s cross platform so it&#8217;s a strong contender.</li>
</ul>


<p>I don&#8217;t really need to learn any of these considering I&#8217;ve accomplished quite a bit with NAnt (You can compile and deploy the <a href="http://radio3.cbc.ca/">CBC Radio 3</a> site in one command). Still, if I can get away from the XML build files tasks would be more concise and easier to extend.</p>

<h4>Implement a Continuous Integration Setup</h4>

<p>I&#8217;ve mentioned how much I love the one line build execution. What I hate is when that one line build execution breaks! I don&#8217;t know a whole lot about CI, but just the ability to have an automated build health check is reason enough for me to implement CI. Automated testing, and deployment are just bonuses. The only one I have some knowledge about is <a href="http://www.cruisecontrolnet.org/">CruiseControl.Net</a> written by the folks at ThoughtWorks. If it&#8217;s good enough for <a href="http://martinfowler.com/">Martin Fowler&#8217;s</a> team, it&#8217;s good enough for me.</p>

<h4>Change Version Control System</h4>

<p><a href="http://subversion.apache.org/">Subversion</a> has changed my life. I wish I had used it (or any versioning system) when in University. In fact, that&#8217;s the first thing I would recommend any new Comp-Sci student to learn is some sort of version system. It&#8217;ll save you so much hassle in the long run, and you&#8217;ll be versioning ninja once you get out into the workforce.</p>

<p>I&#8217;ve been reading about distributed version systems and like the idea of decoupling my repository from a server. I recently found a <a href="http://www.smashingmagazine.com/2008/09/18/the-top-7-open-source-version-control-systems/">great article</a> comparing other systems and there are two other systems that I want to try:</p>

<ul>
<li><a href="http://git-scm.com/">Git</a> - Written by Linus Torvalds, this distributed versioning system is quite powerful and has lots of mainstream support. I&#8217;ve seen discussions where some say Git is a bit too difficult, but once understood is extremely powerful.</li>
<li><a href="http://bazaar-vcs.org/">Bazaar</a> - A distributed version system with a focus on usability. The one interesting note on their website is that their code base has over 10,000 unit tests! Whether or not I use it, I&#8217;m sure the code base would be an interesting read in how to write python applications.</li>
</ul>


<h3>Life Organization:</h3>

<h4>Bookmarks</h4>

<p>I still have great pain in maintaining my browser bookmarks. I use Delicious, and love the FireFox integration, but now that doesn&#8217;t matter now that I&#8217;m using Chrome now. I&#8217;m still brainstorming ideas and may post later about how I&#8217;m going to move forward.</p>

<h4>Calendar</h4>

<p>One of my favourite features of my phone is how it syncs with my work Outlook calendar. The problem is that I&#8217;m not at work all the time (wait, that&#8217;s a problem?). I want an ubiquitous calendar. When I refer to a calendar, I mean the one calendar to rule them all and in darkness&#8230; oops, I mean&#8230; When I say I&#8217;m doing something on a particular date and time, I want my announcement cascaded to all calendar applications I use. Notice I didn&#8217;t say how I announce an appointment. I don&#8217;t want to limit myself to adding events in Outlook, my phone, or my Google apps calendar. So I&#8217;m on the lookout a calendaring strategy that allows me to add events to my &#8220;abstract&#8221; calendar. Good luck with that, eh?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Handy Web Path Concatenation Code]]></title>
    <link href="http://scottmuc.github.com/blog/development/handy-web-path-concatenation-code/" />
    <updated>2008-12-03T16:33:00-08:00</updated>
    <id>http://scottmuc.github.com/blog/development/handy-web-path-concatenation-code</id>
    <content type="html"><![CDATA[<p>Lot of web developement code is spent concatenating path snippets and I always hated having to deal with slashes. I wanted a function that was consistent with its return type, and very loose in its parameter requirements. I ended up with the following:</p>

<!-- more -->


<p><em>Test First</em>:</p>

<div><script src='https://gist.github.com/1545719.js?file=WebPathSpecs.cs'></script>
<noscript><pre><code>using bddunit.core;
using CBC.Radio3.Commons.Specs;
using Observation = MbUnit.Framework.TestAttribute;
using SUT = CBC.Radio3.Commons.Web.WebPath;

namespace CBC.Radio3.Commons.Web
{
    [Concern(typeof (WebPath))]
    public class when_WebPath_Combines_a_bunch_of_strings : ContextSpecification
    {
        private string result;

        protected override void establish_context()
        {
            
        }

        protected override void because()
        {
            result = SUT.Combine(&quot;/slashesonbothsides/&quot;, &quot;//doubleslash//&quot;, &quot;rightslash/&quot;, &quot;/leftslash&quot;, &quot;file.jpg&quot;);
        }

        [Observation]
        public void should_return_an_absolute_web_path()
        {
            result.should_be_equal_to(&quot;/slashesonbothsides/doubleslash/rightslash/leftslash/file.jpg&quot;);
        }
    }
}</code></pre></noscript></div>


<p>The <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">BDD</a> style of testing is inspired (and pretty much copied) from JP Boodhoo&#8217;s Nothing but .Net class.</p>

<p><em>Here&#8217;s the code</em>:</p>

<div><script src='https://gist.github.com/1545719.js?file=WebPath.cs'></script>
<noscript><pre><code>using System.Text;

namespace CBC.Radio3.Commons.Web
{
    public class WebPath
    {
        /// &lt;summary&gt;
        /// Takes a parameter list of strings and returns the strings concatenated with a
        /// preceding '/' character. If the string has a trailing/preceding slash it will
        /// be removed. Any slashes in the middle of the string will remain.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;paths&quot;&gt;&lt;/param&gt;
        /// &lt;returns&gt;Contatenation of paths seperated by directory seperator&lt;/returns&gt;
        public static string Combine(params string[] paths)
        {
            var sb = new StringBuilder();

            foreach (var path in paths)
                sb.AppendFormat(&quot;/{0}&quot;, path.TrimEnd('/').TrimStart('/'));

            return sb.ToString();
        }        
    }
}</code></pre></noscript></div>


<p>That was my first go at it. I have a feeling I might generalize the class to be a delimited string builder. Which would be nice because then the method won&#8217;t be static. Anyways, just thought I would share something that I think is concise but will be used a lot.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Top 5 Things I Cannot Compromise In Web Development]]></title>
    <link href="http://scottmuc.github.com/blog/development/top-5-things-i-can-t-compromise-on-in-web-development/" />
    <updated>2008-11-27T16:33:00-08:00</updated>
    <id>http://scottmuc.github.com/blog/development/top-5-things-i-cannot-compromise-in-web-development</id>
    <content type="html"><![CDATA[<p>Over the past few months I&#8217;ve realized that I&#8217;m a stubborn mule when it comes to certain aspects of web development. After some internal reflection I&#8217;ve come up with my top 5 things I strongly feel that I won&#8217;t compromise on in the web development process. These items are just for the presentation layer, I&#8217;m loaded with issues deeper into the development stack.</p>

<!-- more -->


<p><em>1 - URLs must be as beautiful as possible</em></p>

<p>I really don&#8217;t need to say much about this because <a href="http://mikeschinkel.com/blog/welldesignedurlsarebeautiful/">Mike Schinkel</a> has already said it all. We&#8217;ve been contemplating the use of <a href="http://www.asual.com/swfaddress/">SWFAddress</a> as a method of deep linking because the new <a href="http://radio3.cbc.ca/">Radio 3 website</a> is wrapped in a FrameSet therefore you don&#8217;t see the URL change in the Address bar of a web browser. I know how well deep linking solves this problem, but I still have a hard time looking at a URL with the hash (#). I personally would never use it for a personal website because that 1 character of noise is so distracting to me.</p>

<p>Secondly, I believe urls should be guessable and hackable. <a href="http://stackoverflow.com/">Stackoverlow</a> has some clean urls but they aren&#8217;t perfect. They are somewhat hackable, but what&#8217;s with have the database key in the url? this makes urls impossible to guess. I really wish my profile URL was: http://stackoverflow.com/users/scott-muc instead.</p>

<p><em>2 - Web pages must be constructed with semantic markup with no display decoration</em></p>

<p>Seperating the design from the markup can be difficult but when done correctly it is a thing of beauty. The introduction of <a href="http://microformats.org/">micro-formats</a> has made me see a huge potential in the markup as data and not about display. I&#8217;m extremely impressed by <a href="http://content.corkd.com/">Corkd</a> because you can actually use their website markup as a database for their wine reviews because of their usage of the <a href="http://microformats.org/wiki/hreview">hreview</a> microformat.</p>

<p>Along with that I believe the markup should contain zero inline CSS and javascript. Easier said than done, but I simply believe that CSS should belong in the stylesheet files (or in the page header in the worst case). Inline boot strapping javascript I find ok, but using inline javascript to handle click events is really messy.</p>

<p><em>3 - No browser specific CSS and/or hacks</em></p>

<p>The first time I learned about the <a href="http://css-discuss.incutio.com/wiki/Star_Html_Hack">Star Hack</a> I was in heaven. I finally felt I could make IE 6 work. Unfortunately this hack came with the cost of making CSS maintenance difficult. It takes more time, but having a design that requires the minimal amount of IE 6 only hacks the better. Or better yet, don&#8217;t do any IE 6 hacks and just use <a href="http://www.alistapart.com/articles/progressiveenhancementwithcss">progressive enhancement</a> and don&#8217;t fret about IE 6 looking bad in some situations. It&#8217;s simply not worth the time because we all have better things to do than support a nearly 10 year old web browser.</p>

<p><em>4 - No flash or objects on the page</em></p>

<p>Flash creates a load delay that&#8217;s an order of magnitude slower than a regular text only page load. I do like flash and a lot of the features it provides, but I think the best usage of flash is to only load it when the user wishes to use a feature that requires flash. The embedable music players and the embedded youtube videos are the worst offenders in my humble opinion. These can easily be handled by loading of the flash on click events.</p>

<p><em>5 - Don&#8217;t let your server side application framework take over your markup</em></p>

<p>The majority of my web experience is with Asp.Net and I really don&#8217;t like how some of the controls create horrible markup. I&#8217;m a big fan of the Repeater and ListView controls simply because I have 100% control over the markup they create. I can&#8217;t say I&#8217;ve ever used GridView in a production web site.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[It Is Good To Laugh At Your Old Code]]></title>
    <link href="http://scottmuc.github.com/blog/development/it-s-good-to-laugh-at-your-old-code/" />
    <updated>2008-11-10T16:33:00-08:00</updated>
    <id>http://scottmuc.github.com/blog/development/it-is-good-to-laugh-at-your-old-code</id>
    <content type="html"><![CDATA[<p>One of the things I love about my job is the ability to see myself grow as a developer. I&#8217;m glad I can laugh at my old code because if I can&#8217;t then I&#8217;m definitely not improving my skillset.</p>

<!-- more -->


<p>Here&#8217;s some code from around 3 years ago:</p>

<div><script src='https://gist.github.com/1545686.js?file=UrlRewriteHandler.cs'></script>
<noscript><pre><code>using System;
using System.Web;
using System.Configuration;

using System.Text;
using System.Text.RegularExpressions;
using CBC.Radio3.Core.Web;

namespace CBC.Radio3.Core
{
    public class UrlRewriteHandler : IHttpHandler, System.Web.SessionState.IRequiresSessionState
    {
        // Override the ProcessRequest method.
          public void ProcessRequest(HttpContext context) 
          {
            string path = (context.Request.QueryString[&quot;url&quot;] == null) 
                            ? string.Empty 
                            : Convert.ToString(context.Request.QueryString[&quot;url&quot;]);
            
            string sendToUrl = path;
                        
            RewriterRuleCollection rules = RewriterConfiguration.GetConfig().Rules;
            context.Trace.Write(&quot;ModuleRewriter&quot;, &quot;Url Requested &quot; + path);

            for(int i = 0; i &lt; rules.Count; i++)
            {
                string lookFor = rules[i].LookFor;
                Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);

                if (re.IsMatch(path))
                {
                    sendToUrl = SiteInfo.ApplicationPath + re.Replace(path, rules[i].SendTo);
                    context.Trace.Write(&quot;ModuleRewriter&quot;, &quot;Rewriting URL to &quot; + sendToUrl);
                    
                    string referer               = context.Request.Headers[&quot;Referer&quot;] ?? string.Empty;
                    string permalink             = path;
                    RewriterRuleType ruleType     = UrlRewriteHandler.GetRewriterRuleType(path); 
                    string siteDomain            = SiteInfo.Hostname;
                    
                    if ( !IsBotRequest(context) &amp;&amp; !referer.Contains( siteDomain ))
                    {
                        PermalinkLogger.Instance().Log(permalink, ruleType, referer);
                    }
                    
                    context.Response.Redirect(sendToUrl);
                }
            }
            
            // We haven't found a match so return a 404
            context.Response.Status        = &quot;404 Not Found&quot;;
            context.Response.StatusCode = 404;
          }
 

          private static bool IsBotRequest(HttpContext context)
          {
              return context.Request.Browser.Crawler;
          }

          public bool IsReusable { get { return true; } }
          
          
        public static RewriterRuleType GetRewriterRuleType(string permalink)
        {
            RewriterRuleCollection rules = RewriterConfiguration.GetConfig().Rules;

            for(int i = 0; i &lt; rules.Count; i++)
            {
                string lookFor = rules[i].LookFor;
                Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);

                if (re.IsMatch(permalink))
                {
                    return rules[i].RuleType;
                }
            }
            
            return RewriterRuleType.Undefined;
        } 
        
        public static string GetRuleDataXml(string permalink)
        {
            RewriterRuleCollection rules = RewriterConfiguration.GetConfig().Rules;

            for(int i = 0; i &lt; rules.Count; i++)
            {
                string lookFor = rules[i].LookFor;
                Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);

                if (re.IsMatch(permalink))
                {
                    string xmlData = re.Replace(permalink, rules[i].NodeForm);
                    return xmlData;
                }
            }
            
            return string.Empty;        
        }        
   }
}
</code></pre></noscript></div>


<p>Here&#8217;s what the code I used to replace it:</p>

<div><script src='https://gist.github.com/1545686.js?file=PermalinkProcessingHandler.cs'></script>
<noscript><pre><code>using System.Web;
using CBC.Radio3.Permalinks.Common;

namespace CBC.Radio3.Permalinks.HttpHandlers
{
    public class PermalinkProcessingHandler : IHttpHandler
    {
        private readonly IPermalinkParser permalinkParser;

        public PermalinkProcessingHandler()
            : this(new PermalinkParser())
        {
            
        }

        public PermalinkProcessingHandler(IPermalinkParser permalinkParser)
        {
            this.permalinkParser = permalinkParser;
        }

        public void ProcessRequest(HttpContext context) 
        {
            string permalink = context.Request.QueryString[&quot;url&quot;] ?? string.Empty;

            if (!string.IsNullOrEmpty(permalink) &amp;&amp; permalinkParser.CanParse(permalink))
            {
                string redirectUrl = permalinkParser.GetRedirectUrlFrom(permalink);
                context.Response.Redirect(redirectUrl);
            }

            context.Response.Status        = &quot;404 Not Found&quot;;
            context.Response.StatusCode = 404;
        }

        public bool IsReusable { get { return true; } }
    }
}</code></pre></noscript></div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[JS Builder Exceptions With Multiline JS Strings]]></title>
    <link href="http://scottmuc.github.com/blog/development/js-builder-exceptions-with-multiline-js-strings/" />
    <updated>2008-10-03T16:32:00-07:00</updated>
    <id>http://scottmuc.github.com/blog/development/js-builder-exceptions-with-multiline-js-strings</id>
    <content type="html"><![CDATA[<p>I&#8217;m creating an automated build process and one of the items in the build is to build an external resource which is a java script library. The javascript is contained in multiple files and I want to concatenate them into one script. I found a very useful tool called <a href="http://code.google.com/p/js-builder/">JS Builder</a> which has a command line executable which I can use to automate the construction of this javascript file.</p>

<!-- more -->


<p>Setup was very simple. I created a JS Build project in my build directory. Inside it I reference the .js files I want to include/minimize/concatenate. I select the folder containing the scripts and attempt to run the build.</p>

<p>My first attempt results in the following error:</p>

<p>An unhandled exception occurred while building:</p>

<pre>
System.Exception: Error: JSMIN unterminated string literal: 10
 at JSBuild.JSMin.action(Int32 d)
 at JSBuild.JSMin.jsmin()
 at JSBuild.JSMin.MinifyToString(String src)
 at JSBuild.JavascriptFile.get_Minified()
 at JSBuild.JavascriptFile.MinifyTo(String target)
 at JSBuild.ProjectBuilder.Build(Project project, String outputDir)
 at JSBuild.ProjectBuilder.Build(Project project)
 at JSBuild.MainForm.Build()
</pre>


<p>I tried to google the error but could not find anything. To troubleshoot I added 1 javascript file at a time and found that there were a small group of files that caused this error. It turns out that JS Build chokes on multiline strings that use the &#8216;&#39; character to have the string declared on multiple lines in the source code.</p>

<p>Not a big deal, I did multiline string concatenation to build the strings instead (probably implement a string builder in the future). After that, everything built fine. During the research I came across an <a href="http://kazoolist.blogspot.com/2008/06/multi-line-strings-in-javascript.html">interesting article</a> regarding the validitiy of the syntax of strings using the &#8216;&#39; character.</p>

<p>Now I have a simple NAnt task that executes JS Build that constructs a single javascript file for a complex javascript audio player for the future CBC Radio 3 website (kudos to <a href="http://www.rabin.ca/">Phil Rabin</a> for the code). Next step is to figure out how to deal with thirdparty javascript libraries that the project depends on.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Desktop As My Default Download Location]]></title>
    <link href="http://scottmuc.github.com/blog/why-i-ve-chosen-to-use-my-desktop-as-my-default-download-location/" />
    <updated>2008-09-12T16:32:00-07:00</updated>
    <id>http://scottmuc.github.com/blog/desktop-as-my-default-download-location</id>
    <content type="html"><![CDATA[<p>So I&#8217;ve been getting into the book <a href="http://www.davidco.com/">Getting Things Done</a> lately and can identify with many of the ideas it discusses. The one idea I really like is the consolidation of <a href="http://en.wikipedia.org/wiki/Getting_Things_Done#Collect">Inboxes</a>.</p>

<!-- more -->


<p>I&#8217;m of the camp that likes to have a pristine desktop. I personally think the desktop should never be seen, and if it is then you&#8217;re not managing your windows properly. When things go on my desktop I naturally try to clean them up. I don&#8217;t need any application launchers because I use <a href="http://www.launchy.net/">Launchy</a> for that.</p>

<p>In the past I used to use a dedicated <em>Downloads</em> folder. What has always happened was a convoluted mess of files that I had no idea what they were or not sure if I even needed them. Since the folder was sort of out of the way I let it get messy. Since I already know I&#8217;m crazy about keeping my desktop clean I thought it would be interesting to make it my default download location. The result is that I&#8217;ve been diligent in following <em>GTD</em> actions with the files! If I need the file once I&#8217;m quick to delete it. If it&#8217;s important for something later I put it into a hold folder, and the last case is that I store it for reference.</p>

<p>This probably all sounds obvious, but reading GTD is like reading a <a href="http://www.dofactory.com/">design patterns book</a>. Instead of everything looking like a singleton or a factory, I see things in their context, project, and next action.</p>
]]></content>
  </entry>
  
</feed>

