<?xml version='1.0' encoding='utf-8' ?>
<feed xmlns='http://www.w3.org/2005/Atom'>
  <title type='text'>Ruby Pond</title>
  <generator uri='http://effectif.com/nesta'>Nesta</generator>
  <id>tag:rubypond.com,2009:/</id>
  <link href='http://rubypond.com/articles.xml' rel='self' />
  <link href='http://rubypond.com' rel='alternate' />
  <subtitle type='text'>web site and software development company; internet, email, search, and social marketing services</subtitle>
  <updated>2012-04-11T16:12:00+00:00</updated>
  <author>
    <name>Glenn Gillen</name>
    <uri>http://glenngillen.com</uri>
    <email>glenn@glenngillen.com</email>
  </author>
  <entry>
    <title>Default environment specific values for DATABASE_URL</title>
    <link href='http://rubypond.com/blog/default-value-for-database-url' rel='alternate' type='text/html' />
    <id>tag:rubypond.com,2012-04-11:/blog/default-value-for-database-url</id>
    <content type='html'>&lt;p&gt;If you&amp;#39;ve been following the intelligent advice from &lt;a href=&quot;http://www.12factor.net/&quot;&gt;12 Factor&lt;/a&gt;
when building your application then you&amp;#39;ll know that environment variables
are the correct place to specify settings for your environment. Crazy eh?&lt;/p&gt;

&lt;p&gt;However this is at odds with the assumptions and conventions in Rails that
&lt;code&gt;database.yml&lt;/code&gt; is the canonical source of all your database configs. Having
to export your environment variables any time you want to change
the environment of the app, or over-riding in &lt;code&gt;test_helper&lt;/code&gt;/&lt;code&gt;spec_helper&lt;/code&gt;
is needless pain.&lt;/p&gt;

&lt;h2&gt;Keeping DATABASE_URL and database.yml consistent&lt;/h2&gt;

&lt;p&gt;Instead of having to manage all this manually, lets just let Rails win
for now by setting &lt;code&gt;DATABASE_URL&lt;/code&gt; to the value(s) defined within &lt;code&gt;database.yml&lt;/code&gt;.
No more having to set default values in your helpers, no more re-exporting
your environment locally when you want to change modes, no more exports
if you&amp;#39;re using libraries that assume you&amp;#39;re configuring your app in an
intelligent and scalable way (like &lt;a href=&quot;https://github.com/ryandotsmith/queue_classic&quot;&gt;queue_classic&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Add this to your &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem &amp;quot;rails-database-url&amp;quot;&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#39;s it. Source is &lt;a href=&quot;https://github.com/glenngillen/rails-database-url&quot;&gt;on GitHub&lt;/a&gt;, pull requests
gladly accepted if you find any bugs.&lt;/p&gt;</content>
    <published>2012-04-11T16:12:00+00:00</published>
    <updated>2012-04-11T16:12:00+00:00</updated>
    <category term='ruby-on-rails'></category>
  </entry>
  <entry>
    <title>Simplifying ActiveRecord Connection Strings</title>
    <link href='http://rubypond.com/blog/activerecord-url-connections' rel='alternate' type='text/html' />
    <id>tag:rubypond.com,2011-07-24:/blog/activerecord-url-connections</id>
    <content type='html'>&lt;p&gt;Over the years I&amp;#39;ve gone to great lengths to avoid committing production
passwords into version control. With Rails this has inevitably meant a
number of different ways to ensure the &lt;code&gt;database.yml&lt;/code&gt; was where it needed to
be on the production servers, with the right credentials. Custom Capistrano
recipes to create a new config when setting up a server, moving it into
place after a deploy, it worked well enough but it&amp;#39;s always felt a little
heavy.&lt;/p&gt;

&lt;h2&gt;There&amp;#39;s got to be a better way&lt;/h2&gt;

&lt;p&gt;There are a whole range of configuration settings that are environment
dependent. Which database to connect to, what queues Resque workers should
listen to, the Rack/Application environment mode. What we need is a
standard way on each server to set these environment variables. Oh hang on,
environment variables!&lt;/p&gt;

&lt;p&gt;It&amp;#39;s easy enough to either export an environment variable in a shell, or
pass it in with the command like &lt;code&gt;RACK_ENV=production rackup config.ru&lt;/code&gt;
but a more complicated configuration like ActiveRecord requires doesn&amp;#39;t
quite work like that. It&amp;#39;s expecting a Hash that defines the database
adapter to use, username, password, the database, a host, and possibly a
bunch of other options. We could probably serialise that back and forth
between a Hash and something like JSON but it feels like a bit of a hack.&lt;/p&gt;

&lt;p&gt;What would be better is if we could come up with a simple and uniform string
format that could define how to locate any resource, including a database. I
propose we call such a string a Uniform Resource Locator, or URL for short ;)&lt;/p&gt;

&lt;h2&gt;Using URLs to connect to databases&lt;/h2&gt;

&lt;p&gt;This isn&amp;#39;t a new technique, other ORMs like Sequel have been doing this for
years. It&amp;#39;s just that ActiveRecord hasn&amp;#39;t supported it, until now. I&amp;#39;ve
created a gem that adds support for URL based connections to ActiveRecord,
it&amp;#39;s called &lt;a href=&quot;https://github.com/glenngillen/activerecord_url_connections&quot;&gt;activerecord_url_connections&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Add it to your &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem &amp;quot;activerecord_url_connections&amp;quot;&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now you can connect to your database by adding the following to an
initializer (e.g., &lt;code&gt;config/initializers/activerecord.rb&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ActiveRecord::Base.establish_connection(ENV[&amp;quot;DATABASE_URL&amp;quot;])&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can either export the &lt;code&gt;DATABASE_URL&lt;/code&gt; environment variable in your
app environment or set it when you start your app like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;DATABASE_URL=postgres://localhost/myapp_production&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No more juggling &lt;code&gt;database.yml&lt;/code&gt; on production servers, no risk of checking
sensitive credentials into version control.&lt;/p&gt;

&lt;h2&gt;Convention Over Configuration&lt;/h2&gt;

&lt;p&gt;Something still doesn&amp;#39;t feel quite right about this approach though. Creating
an initializer just to have that one line seems a bit needless, especially
when it will be exactly the same in almost every app. So in much the same
way Rails assumes a default connection to use if you don&amp;#39;t provide one, so
it will look to see if you&amp;#39;ve set &lt;code&gt;DATABASE_URL&lt;/code&gt; and use it when available.&lt;/p&gt;

&lt;p&gt;Stick with the conventions, and you&amp;#39;ll not need to do anything beyond adding
the gem and setting &lt;code&gt;DATABASE_URL&lt;/code&gt;. Sweet!&lt;/p&gt;

&lt;h2&gt;But wait, there&amp;#39;s more!&lt;/h2&gt;

&lt;p&gt;There&amp;#39;s some further good news too. Firstly, for anyone using Heroku for
hosting Rack apps that use ActiveRecord this means connection to your
database will &amp;quot;just work&amp;quot; (it&amp;#39;s not needed for Rails as Heroku create a
&lt;code&gt;database.yml&lt;/code&gt; file so the existing Rails behaviour will work). Secondly
this change has made it into ActiveRecord for the 3.2 release so you&amp;#39;ll
only need this gem to backport the behaviour to previous releases.&lt;/p&gt;</content>
    <published>2011-07-24T21:00:00+00:00</published>
    <updated>2011-07-24T21:00:00+00:00</updated>
    <category term='ruby-on-rails'></category>
  </entry>
  <entry>
    <title>Slaying dragons with git, bash, and ruby</title>
    <link href='http://rubypond.com/blog/slaying-dragons-git-bash-ruby' rel='alternate' type='text/html' />
    <id>tag:rubypond.com,2010-09-07:/blog/slaying-dragons-git-bash-ruby</id>
    <content type='html'>&lt;p&gt;An often over-looked feature when using git are the &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/githooks.html&quot;&gt;various hooks&lt;/a&gt; you have available. They cover &lt;code&gt;pre-applypatch&lt;/code&gt;, &lt;code&gt;post-update&lt;/code&gt;, and anything between or beyond. I suspect a lot of people may have first been introduced to them when integrating with a Continuous Integration server as a means of telling it to test a new build, but they work equally well as a hidden monkey saving your from showing the world some of your more embarrassing mistakes.&lt;/p&gt;

&lt;h2&gt;Getting started with git hooks&lt;/h2&gt;

&lt;p&gt;Within your cloned git repository you&amp;#39;ll most likely be aware of the &lt;code&gt;.git/&lt;/code&gt; directory. Within there you&amp;#39;ll have another directory called &lt;code&gt;hooks/&lt;/code&gt; which, surprise surprise, your git-hooks live. You&amp;#39;ll probably have a bunch of existing hooks in there with .sample as the extension to stop them being executed, it&amp;#39;s worth taking a look at them to get an overview of the various hooks and what is possible.&lt;/p&gt;

&lt;p&gt;To get a hook to fire you need a file with the appropriate name (remove the .sample extension on each file you want to run), and it needs to be granted execute permissions:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ chmod +x .git/hooks/hook-name-here&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Joining forces for real ultimate power&lt;/h2&gt;

&lt;p&gt;Coding in ruby most the day makes it the quickest language for me to use to throw together a script. Thankfully you can write you hooks in ruby, or just about any language really, just change the shebang line accordingly:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;#!/usr/bin/env ruby&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However there are lots of things that are much easier to do from a command line than they are in a ruby script, and so we will stand on the shoulders of giants and use the underlying *nix tools to do what they&amp;#39;re best at, and use ruby to keep things re-usable and readable.&lt;/p&gt;

&lt;h2&gt;Catching out bad habits&lt;/h2&gt;

&lt;p&gt;One thing I&amp;#39;ve been guilty of in the past is hastily trying to fix a bug, and then accidentally leaving a debug breakpoint in the committed code. If that ever made it onto a production system it would leave it hanging and unresponsive. Even on other developer machines it causes enough confusion. So to make me look much more reliable than I really am, enter the git &lt;code&gt;pre-commit&lt;/code&gt; hook:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;#!/usr/bin/env ruby&amp;#x000A;if `grep -rls &amp;quot;require &amp;#39;ruby-debug&amp;#39;; debugger&amp;quot; *` != &amp;quot;&amp;quot;&amp;#x000A;  puts &amp;quot;You twit, you&amp;#39;ve left a debugger in!&amp;quot;&amp;#x000A;  exit(1)&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now whenever I try to commit code, it will first run a recursive &lt;code&gt;grep&lt;/code&gt; over the codebase to ensure I&amp;#39;ve not left my debug statement in (I can be sure it always looks like &amp;quot;require &amp;#39;ruby-debug&amp;#39;; debugger&amp;quot; as I have it bound to a shortcut).&lt;/p&gt;

&lt;h2&gt;Stopping an incomplete merge&lt;/h2&gt;

&lt;p&gt;There&amp;#39;s been occasions where a particularly large rebase or merge creates a lot of conflicts in a file, and one of those has snuck through and rather than being fixed the inline diff has actually been committed. Time to add another check to &lt;code&gt;pre-commit&lt;/code&gt;, using &lt;code&gt;egrep&lt;/code&gt; to scan recursively for the 3 different line markers that git uses to indicate a merge conflict:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;#!/usr/bin/env ruby&amp;#x000A;&amp;#x000A;if `egrep -rls &amp;quot;^&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; |^&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; |^=======$&amp;quot; *`&amp;#x000A;  puts &amp;quot;Dang, looks like you screwed the merge!&amp;quot;&amp;#x000A;  exit(1)&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you try this though you&amp;#39;ll probably discover that it doesn&amp;#39;t quite work as expected, because there are some binary files that happen to include these characters. More shell scripting to the rescue then, we will pipe the results into a couple of other commands to filter it out. First it goes via &lt;code&gt;xargs&lt;/code&gt; to allow us to take the input from STDIN and pass each line recursively into &lt;code&gt;file&lt;/code&gt; to find out what type of file we are dealing with. We then pipe that into &lt;code&gt;egrep&lt;/code&gt; again to select only the script and text files:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;#!/usr/bin/env ruby&amp;#x000A;&amp;#x000A;if `egrep -rls &amp;quot;^&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; |^&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; |^=======$&amp;quot; * | xargs file | egrep &amp;#39;script|text&amp;#39;` != &amp;quot;&amp;quot;&amp;#x000A;  puts &amp;quot;Dang, looks like you screwed the merge!&amp;quot;&amp;#x000A;  exit(1)&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It would be nice at this point to actually know what files have been affected, without needing to commit the above series of commands to memory, so we can output it again this time passing the result into &lt;code&gt;awk&lt;/code&gt; to strip out just the filename:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;#!/usr/bin/env ruby&amp;#x000A;&amp;#x000A;if `egrep -rls &amp;quot;^&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; |^&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; |^=======$&amp;quot; * | xargs file | egrep &amp;#39;script|text&amp;#39;` != &amp;quot;&amp;quot;&amp;#x000A;  puts &amp;quot;Dang, looks like you screwed the merge!&amp;quot;&amp;#x000A;  puts `egrep -rls &amp;quot;^&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; |^&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; |^=======$&amp;quot; * | xargs file | egrep &amp;#39;script|text&amp;#39; | awk -F: &amp;#39;{print $1}&amp;#39;`&amp;#x000A;  exit(1)&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Helping your workflow&lt;/h2&gt;

&lt;p&gt;I&amp;#39;m a big fan of committing regularly in manageable amounts, but I want to ensure each commit is self-contained and has all the tests passing. I don&amp;#39;t want to be in a state where I revert a commit and end up with a broken app. However, there are times where I&amp;#39;ll be spiking something or refactoring a class and I&amp;#39;d like a temporary save point incase I make a mess of things and want to step back. To do that, I typically commit with a message like &amp;quot;WiP: Got Foo working, about to fix Bar.&amp;quot; with the intention of coming back when it&amp;#39;s complete and amending that commit to include the additional changes and have a more meaningful message. Sometimes I forget to use &lt;code&gt;--amend&lt;/code&gt; though and things don&amp;#39;t go to plan. That&amp;#39;s another one that is easy to avoid:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;#!/usr/bin/env ruby&amp;#x000A;&amp;#x000A;if `git log --oneline --author=\`git config --get-all user.email | sed s/@.*//g\` -n 5 | grep -i wip` != &amp;quot;&amp;quot;&amp;#x000A;  puts &amp;quot;You&amp;#39;ve left a WiP commit message behind&amp;quot;&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You might need to do a little tweaking on that one depending on your setup, so I&amp;#39;ll break it out in the order the commands will be executed to help you modify to your needs. First, I use &lt;code&gt;git-config&lt;/code&gt; to return the email address of the current user:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ git config --get-all user.email&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I then pipe that into &lt;code&gt;sed&lt;/code&gt; to return just the bit before the @ sign:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ sed s/@.*//g&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#39;s all been executed in a sub-process (I&amp;#39;ve backslash escaped the back tick characters at each end of the command: &amp;quot;git config --get-all user.email | sed s/@.*//g&amp;quot;). The result of that command is passed into &lt;code&gt;git-log&lt;/code&gt; to return the last 5 commits for that author:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ git log --oneline --author=username_here -n 5&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And finally, &lt;code&gt;grep&lt;/code&gt; is called on the result to ensure I haven&amp;#39;t left the string &amp;quot;wip&amp;quot; in any of the commits:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ grep -i wip&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Ensuring you don&amp;#39;t break the build&lt;/h2&gt;

&lt;p&gt;The hook that kicked it all off for me was to ensure that I didn&amp;#39;t break the build, mostly as an attempt to claim moral superiority over anyone else who was found guilty of doing it themselves. Little did they know I had a secret weapon to protect my perfect performance ;)&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;#!/usr/bin/env ruby&amp;#x000A;&amp;#x000A;puts &amp;quot;Running tests...&amp;quot;&amp;#x000A;`rake test &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&amp;amp; bundle exec cucumber features &amp;gt; /dev/null 2&amp;gt;&amp;amp;1`&amp;#x000A;if $? != 0&amp;#x000A;  puts &amp;quot;Tests failed&amp;quot;&amp;#x000A;  exit(1)&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Making it more self-aware&lt;/h2&gt;

&lt;p&gt;This approach worked great for a couple of days, but I quickly got frustrated because I&amp;#39;d have to add the &lt;code&gt;--no-verify&lt;/code&gt; parameter to commits quite regularly. I really only wanted to run &lt;em&gt;all&lt;/em&gt; the tests when I was committing on master before I pushed changes upstream to everyone else. The other problem was that my &amp;quot;WiP&amp;quot; workflow meant I&amp;#39;d have to use &lt;code&gt;--no-verify&lt;/code&gt; whenever I was amending a commit and it struck me the script should be intelligent enough to know I was trying to do the right thing.&lt;/p&gt;

&lt;h3&gt;Detecting master&lt;/h3&gt;

&lt;p&gt;Determining if the current branch was master was relatively straight-forward:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;`git symbolic-ref HEAD | grep master` != &amp;quot;&amp;quot;&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So just wrap that as part of the if statements you only want to be executed when you&amp;#39;re on the master branch.&lt;/p&gt;

&lt;h3&gt;Detecting commit amend&lt;/h3&gt;

&lt;p&gt;Working out if you are amending a commit is a little trickier. The options passed to &lt;code&gt;commit&lt;/code&gt; aren&amp;#39;t passed through to your script, so it requires a bit of process hackery in both ruby and bash to find out if &lt;code&gt;--amend&lt;/code&gt; was used. First we use the built in &lt;code&gt;$$&lt;/code&gt; variable in ruby to return the process ID of the ruby process, and use it with &lt;code&gt;ps&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; to return all matching processes:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;`ps -f | grep #{$$}`&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We then pass that into &lt;code&gt;awk&lt;/code&gt; to extract the parent&amp;#39;s process ID, and make an assumption that the first line is the parent:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;`ps -f | grep #{$$} | awk &amp;#39;{print $3}&amp;#39; | head -n 1`&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Back into &lt;code&gt;ps&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; again now that we have the process ID of the parent we use it to return the full command and options that were passed to &lt;code&gt;git-commit&lt;/code&gt;, and then &lt;code&gt;grep&lt;/code&gt; again to see if &lt;code&gt;--amend&lt;/code&gt; was passed in:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;`ps | grep \`ps -f | grep #{$$} | awk &amp;#39;{print $3}&amp;#39; | head -n 1\` | grep -e &amp;quot;--amend&amp;quot;`&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Phew!&lt;/p&gt;

&lt;h2&gt;Wrapping it all up&lt;/h2&gt;

&lt;p&gt;All that would create a mess of if statements and duplication throughout your git &lt;code&gt;pre-commit&lt;/code&gt; hook, and any other hook you might want to apply this logic to so I&amp;#39;ve &lt;a href=&quot;http://github.com/rubypond/githooks&quot;&gt;bundled it all up in a reusable class&lt;/a&gt; that I include in any project. I&amp;#39;ll keep updating it as my needs develop, feel free to fork it and add features for other languages and frameworks.&lt;/p&gt;</content>
    <published>2010-09-07T13:45:00+00:00</published>
    <updated>2010-09-07T13:45:00+00:00</updated>
  </entry>
  <entry>
    <title>Agile Development: The quickstart guide to doing it right</title>
    <link href='http://rubypond.com/blog/quickstart-guide-to-agile' rel='alternate' type='text/html' />
    <id>tag:rubypond.com,2010-09-06:/blog/quickstart-guide-to-agile</id>
    <content type='html'>&lt;p&gt;Lots of places don&amp;#39;t do agile right, in fact most do it wrong. There are a number of factors why, chief among them I believe is that the percentage of people who have worked somewhere that nailed it completely right is so low that there aren&amp;#39;t enough to go around and lead by example. So here are a few of the tips I&amp;#39;ve been given or learnt over the years, credit has to be given to &lt;a href=&quot;http://glenngillen.com/resume&quot;&gt;all the wonderful places I&amp;#39;ve worked&lt;/a&gt; over the years. The ones that have done it well, and the ones that have done it poorly&amp;hellip; you can learn just as much from reflecting on where it all went wrong.&lt;/p&gt;

&lt;h2&gt;Back to basics&lt;/h2&gt;

&lt;p&gt;Are you already using agile, or are you planning on implementing it in your company? If you&amp;#39;re reading this chances are something isn&amp;#39;t working as well as you&amp;#39;d like and so it&amp;#39;s time to reset. First thing to do is throw out your preconceptions on agile, ignore almost everything you&amp;#39;ve read in practitioner manuals, because at it&amp;#39;s core it&amp;#39;s really quite simple. Most problems stem from people picking only certain features of agile or trying to let a tool guide the process for them. &lt;/p&gt;

&lt;h3&gt;Refocus on the manifesto&lt;/h3&gt;

&lt;p&gt;It&amp;#39;s worth going back and looking at the &lt;a href=&quot;http://agilemanifesto.org/&quot;&gt;agile manifesto&lt;/a&gt; and then questioning each aspect of your process to ensure it is giving priority to the values on the left side. If it&amp;#39;s not, remove it.&lt;/p&gt;

&lt;h3&gt;Throw out the tools you&amp;#39;re using&lt;/h3&gt;

&lt;p&gt;Scrumworks? Urgh! VersionOne? Atlassian? They&amp;#39;re all cut from a similar cloth. If you&amp;#39;re not already doing agile correctly, they will just get in the way. So until you&amp;#39;re up and running, get them as far away as possible.&lt;/p&gt;

&lt;p&gt;For planning, all you need are some index cards and a pen. If that doesn&amp;#39;t offer you enough protection for your DRP or wont work because you&amp;#39;ve got a distributed team then use a wiki. Again, avoid at all costs anything more complicated until you&amp;#39;ve got it all working.&lt;/p&gt;

&lt;h2&gt;Planning&lt;/h2&gt;

&lt;p&gt;The great thing about stripping it back to basics is that it re-aligns focus on the things that are important, you&amp;#39;re not distracted about calculating backlog points and predicting velocity. Instead you are collaborating with your customer to understand what they will consider working software.&lt;/p&gt;

&lt;h3&gt;You need to become the customer&lt;/h3&gt;

&lt;p&gt;I mentioned in my last post, &lt;a href=&quot;http://rubypond.com/blog/nobody-cares-what-tools-you-use&quot;&gt;nobody cares what tools you use&lt;/a&gt;, your customer is trusting you to make the right decisions to do the best job. You can only really do that when you understand the requirements completely, a full and deep appreciation for &lt;em&gt;why&lt;/em&gt; the work is being done and not simply &lt;em&gt;what&lt;/em&gt; needs to be implemented.&lt;/p&gt;

&lt;p&gt;Your customer is unlikely to be a software developer so their scope, as broad as it is will be, is limited by their experience. They also can&amp;#39;t possibly know upfront all the questions you want answered and all the seemingly irrelevant detail that would feed in to giving the best user experience possible. Expecting them to bridge this gap is completely unrealistic, instead the gap needs to be bridged by having the developers move towards the customer. The developer needs to be completely bought in to the product, understand the problems it solving, and how they&amp;#39;d best be solved.&lt;/p&gt;

&lt;p&gt;This is precisely the reason why &lt;a href=&quot;http://rubypond.com/blog/you-dont-win-friends-with-salad&quot;&gt;tools like cucumber don&amp;#39;t work&lt;/a&gt;, they are bridging that gap from the wrong direction. And if we go back to the agile manifesto, that approach carries the potential to skew the priority back towards contract negotiation rather that customer collaboration.&lt;/p&gt;

&lt;h3&gt;Customers don&amp;#39;t write the stories&lt;/h3&gt;

&lt;p&gt;And neither do business analysts, development managers, or project managers. I&amp;#39;d go so far to say that if you want to be &amp;quot;agile&amp;quot; and you&amp;#39;ve got a team of BAs then you should fire them all. Anybody getting between the developer(s) and the customer is stopping the developer from becoming the customer. Crucial detail will be missed and misplaced assumptions will go unchallenged. Sure, you&amp;#39;ll still get a product out the door but it will either be what was agreed (which is often different to what is actually wanted) or it will not be as awesome as it could have been.&lt;/p&gt;

&lt;p&gt;The people that get between developer and customer have the best of intentions, they&amp;#39;re trying to let developers focus on writing code. I&amp;#39;ll say it again though, they&amp;#39;re job isn&amp;#39;t to write code it&amp;#39;s to deliver a solution. It&amp;#39;s a false economy to think you&amp;#39;re saving the developer time by taking on the requirements analysis on their behalf, it will take longer for them to appreciate 3rd hand the requirements than the half day it would take to know them first hand &lt;em&gt;and&lt;/em&gt; write them up themselves.&lt;/p&gt;

&lt;p&gt;Pull up your sleeves, get out a set of index cards, some pens, and some A4 paper. No laptops, no ipads, no technology. Force the customer to explain the issue without computer aids as though you know nothing. Each of you draw up wireframes, compare the differences between them to see what assumptions have been made, write the card together. Make it a tactile experience.&lt;/p&gt;

&lt;p&gt;The result should be a concise description or the business problem, and the end-user benefit you&amp;#39;re trying to deliver. Never more than a couple of sentences (maybe a few footnotes for pertinent implementation details that can&amp;#39;t be neglected).&lt;/p&gt;

&lt;h3&gt;The most important stories get done first&lt;/h3&gt;

&lt;p&gt;This part of it will be difficult, if not impossible, for the developer to make a judgement call on. It is often very difficult even for the customer, but it has to be done. That being said, it shouldn&amp;#39;t be as difficult as many people make it. If you&amp;#39;re working on a new app that&amp;#39;s not yet been released I&amp;#39;ve got &lt;a href=&quot;http://rubypond.com/images/scheduling-stories.png&quot;&gt;a diagram to help you evaluate priorities&lt;/a&gt;. It&amp;#39;s also worth keeping a focus on getting the smallest usable feature set out the door as soon as possible. Eric Ries said a good way to get to that point is to outline the minimum features you think you need before you can release it publicly, and then you can probably reduce it by 90%. You always need much, much, much less than you ever expect.&lt;/p&gt;

&lt;p&gt;If it&amp;#39;s an existing app and you&amp;#39;re having problems prioritising it might be worth speaking to some users. Just make sure you keep focus on doing the smallest and simplest thing possible to meet the requirement.&lt;/p&gt;

&lt;p&gt;A good way to gauge if story is really &lt;em&gt;the&lt;/em&gt; next most important thing to get completed is to double the estimate, if that changes the priority in the customer&amp;#39;s eyes it wasn&amp;#39;t as important as they thought.&lt;/p&gt;

&lt;h3&gt;If you&amp;#39;re not doing the work, you don&amp;#39;t get to estimate it&lt;/h3&gt;

&lt;p&gt;It took me a long time to appreciate this as a manager, I was often guilty of sizing up tasks based on how long I thought it would take me to complete it. Then someone else picks it up and I wonder why it took so long. Truth is it would always take me longer too but that is too easily forgotten, do you really have a load factor of 1? I thought not.&lt;/p&gt;

&lt;p&gt;How easy or difficult a task is has so many variables: familiarity with the code base, how recently you&amp;#39;ve solved a similar problem, access to an existing solution, etc. and each of those come from a fairly personal experience. Sit down, with a pair to rationalise the decision if you like, and come to a conclusion you&amp;#39;re happy with. The important thing is that you are consistently optimistic/pessimistic on your approach, it&amp;#39;s less important to get the estimate right than it is to be wrong on a relatively consistent basis. Everything averages out very quickly when it comes to the planning.&lt;/p&gt;

&lt;h3&gt;Don&amp;#39;t mention time&lt;/h3&gt;

&lt;p&gt;Do everything you can to avoid estimating in hours or days. No matter how much you explain things like load factor when you see a story with &amp;quot;2 days&amp;quot; or &amp;quot;8 hours&amp;quot; written next to it people can&amp;#39;t help but think that is how long the task will take. So you can&amp;#39;t be entirely shocked when 3 days in they ask how that task that was meant to take 2 days is going. Avoid the awkward situations completely by not setting the expectation in the first place. &lt;/p&gt;

&lt;p&gt;Estimate in points, or jelly beans, or anything other than hours or something that can be tracked by a watch or calendar.&lt;/p&gt;

&lt;h3&gt;Estimates aren&amp;#39;t guesses, but they&amp;#39;re not accurate either&lt;/h3&gt;

&lt;p&gt;Don&amp;#39;t take a look at a story, close your eyes, and come up with a number. Take the time to analyse in detail what is required, what systems you&amp;#39;ll need to talk to, read the 3rd party API/integration docs. Spend a whole day or more if you have to and write up a detailed list of tasks in the order you expect to tackle them, including any decisions on implementation you may come to, and put them at the bottom of your story card.&lt;/p&gt;

&lt;p&gt;Time invested here pays for itself two-fold later in the iteration by maintaining focus on the minimum set of tasks that need to be completed and setting your direction each step of the way. Plus it gives you confidence that the task is achievable and unlikely to blowout.&lt;/p&gt;

&lt;p&gt;When it comes to putting a number (points, jelly bean, whatever) on an estimate I now always advocate a 3 point system. 1 point roughly equates to a half day of effort (ssshhh, don&amp;#39;t tell the customer ;), 2 points a whole day, 3 points 2 days. The reason being that it&amp;#39;s too difficult to consistently estimate small tasks, if you estimate an hour for something and you get snagged and it takes you the first half of a day (not unusual) you&amp;#39;ve blown the estimate by 400%. At the other end of the spectrum you&amp;#39;ve got two problems, either a story that isn&amp;#39;t really implementing the most simple solution possible or a broad scope that it&amp;#39;s difficult to really sit down and estimate in the detail required to be confident in it.&lt;/p&gt;

&lt;p&gt;If the tasks are obviously much smaller than 1 point, I&amp;#39;ll try and group a couple of similar smaller tasks into a single 1 point task. If a task is bigger than 3 points, I&amp;#39;ll split it into separate deliverable parts. &amp;quot;But it&amp;#39;s really a 5 point task, everything has to be delivered at once!&amp;quot;, Bollocks!&lt;/p&gt;

&lt;h3&gt;Estimates for work that isn&amp;#39;t scheduled are worthless&lt;/h3&gt;

&lt;p&gt;They might be useful for getting a high-level idea of when some story might be delivered, maybe, if it&amp;#39;s ever actually scheduled. Remember one of the core tenements of agile is responding to change, and nothing impacts priorities like actually giving software to users. So it&amp;#39;s not uncommon for that really-urgent-we&amp;#39;ve-gotta-have-it next feature to get bumped for a glaring hole a bunch of users pointed out. And then bumped again for something else. It comes back to expectation management again, and putting an estimate next to it adds a misplaced finality to where the story sits in the priority queue.&lt;/p&gt;

&lt;p&gt;The other issue is that each iteration of development feeds back into next. Some previously completed work may make a later story easier to implement, or it may actually highlight that something is more difficult than originally expected. Either way there are enough factors that can completely invalidate whatever estimates you come up with.&lt;/p&gt;

&lt;h2&gt;Execution&lt;/h2&gt;

&lt;p&gt;Once the planning is done, it is down to actually starting the work. It&amp;#39;s not always a matter of ticking boxes off the work list though, the most effective teams I&amp;#39;ve worked in have shared some common traits.&lt;/p&gt;

&lt;h3&gt;Start mid-week&lt;/h3&gt;

&lt;p&gt;Few people love a Monday morning and getting motivated can sometimes be an issue. If you compound that difficulty by expecting everyone to be in the right mindset to sit down and write stories, well it doesn&amp;#39;t always work out for the best. There is no real long-term cost associated with moving the start of the iterations from a Monday to a Wednesday, but allowing me to be productive first thing after a hazy weekend by allowing me to look at a list of work and just crack on with it is a huge win.&lt;/p&gt;

&lt;h3&gt;Have a fixed iteration length&lt;/h3&gt;

&lt;p&gt;I prefer to work with 2 week iterations, 1 week feels too short and 4 too long. &lt;/p&gt;

&lt;p&gt;There is a comfort that comes from having some order to the world, and the importance of the general psyche and morale of a team is often underestimated. On those times that a story does take longer than expected, it&amp;#39;s nice to know that you&amp;#39;ve still got a week or so to make it up. It&amp;#39;s also great to have a regular sense of completion in predictable intervals, the dreaded risk of being stuck on the same task that is going to take months never materialises (partly because you never schedule a story with more than 2 days of effort, right?). There is a lot of subtlety in the impact this predictability has on developers which makes it hard to pinpoint all the benefits, but when combined they all make for a happier environment.&lt;/p&gt;

&lt;p&gt;From a management perspective, it&amp;#39;s great to have some clarity on when things are going to be delivered. And I&amp;#39;m not just talking about for the next fortnight, but you know on a specific day each and every fortnight something is going to be delivered. So does the rest of the team. It makes planning much easier, people know the most convenient windows to take holidays, and which days to stay home are particularly inconvenient because you&amp;#39;re planning with the customer.&lt;/p&gt;

&lt;h3&gt;Developer attention is a premium&lt;/h3&gt;

&lt;p&gt;Jason Fried from 37signals has a great video explaining &lt;a href=&quot;http://bigthink.com/ideas/18522&quot;&gt;why you can&amp;#39;t work at work&lt;/a&gt; that I&amp;#39;d recommend watching. When you&amp;#39;re deep in the coding zone nothing is more disrupting to your flow than someone coming and interrupting you to ask you for opinion on something completely unrelated. That 10 minute interruption can take 30 minutes to recover from fully to get you back into the same state. If they happen 2-3 times a day that is up to 25% of the workday productivity lost to distractions.&lt;/p&gt;

&lt;p&gt;And as Jason mentions in the video the very action is basically a way of saying &amp;quot;Hey, my immediate needs are more important than whatever you&amp;#39;re focussing on, give me attention&amp;quot;. It&amp;#39;s selfish and unhealthy for productivity. Remove phones. Email people if you have to, but don&amp;#39;t expect a response that day. Inter-team or important but non-urgent questions should be posed via an instant messenger, chat program, or something that doesn&amp;#39;t demand immediate interruption (like phones and meetings do). What about things that are urgent? Well that needs to be assessed on a case-by-case basis, but the truth is truly urgent things happen very very rarely. Almost everything can wait at least 4 hours.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s here that a good development manager can work wonderfully, acting as bouncer and preventing direct access to developers while they&amp;#39;re busy coding and filtering the urgency of all requests. &lt;/p&gt;

&lt;h3&gt;Pair Programming&lt;/h3&gt;

&lt;p&gt;A fairly contentious part of agile is pair programming. When it works well, it&amp;#39;s hugely efficient and carries lots of additional benefits (higher quality code, quicker delivery, lower documentation requirements, less &amp;quot;single developer&amp;quot; business risk, etc.) but when it&amp;#39;s implemented poorly it&amp;#39;s just a waste of a resource. In most places I&amp;#39;ve worked it sadly falls into the latter camp, and it&amp;#39;s because people are just paying lip-service to the practice and working it as mentor/tutor type role rather than a pair actively writing code together.&lt;/p&gt;

&lt;p&gt;That&amp;#39;s not to say it doesn&amp;#39;t also offer great potential as an approach to training, the important thing is both participants need to be as involved and active in writing the code.&lt;/p&gt;

&lt;h4&gt;Owning the workspace&lt;/h4&gt;

&lt;p&gt;The biggest problem when it doesn&amp;#39;t work is normally down to the setup of the workspace. Generally Person B brings their chair over to share Person A&amp;#39;s desk, and Person A stays almost exactly where they were to begin with. It&amp;#39;s guaranteed to fail. Here&amp;#39;s what you need to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Share a single monitor, you both need to be looking at the same screen. They&amp;#39;re big enough these days that you can see everything you need with appropriate window management.&lt;/li&gt;
&lt;li&gt;Each person gets their own keyboard and mouse, no co-piloting on shared inputs and it&amp;#39;s not fine to have one person with a keyboard and the other person using the laptop it&amp;#39;s connected to.&lt;/li&gt;
&lt;li&gt;Divide the screen in half, then mark that virtual line on the desk with some tape or a marker&amp;hellip; right down the desk. Each person gets their side and never should they encroach on the other half.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It might all seem a bit contrived and naff, but it makes a difference to the efficiency of the operation. Body position plays on the sub-conscious and determines whether you feel comfortable using the keyboard in front of you. Sitting too far to the side and you start to feel that you&amp;#39;re a spectator on somebody else&amp;#39;s computer, too far in front and you feel like you&amp;#39;re a pilot and co-pilot rather than peers.&lt;/p&gt;

&lt;h4&gt;Everyone is in their own context&lt;/h4&gt;

&lt;p&gt;You&amp;#39;re going to know what programs you need open to get the job done. For me it&amp;#39;s an IDE, a terminal or 3, and a web browser or the running application. Agree on a common screen layout where everything can be seen at the same time, and then mandate it across the entire team (I&amp;#39;ve found &lt;a href=&quot;http://www.mizage.com/divvy/&quot;&gt;Divvy&lt;/a&gt; really useful to keep it consistent). It means that when you come to someone else&amp;#39;s computer it doesn&amp;#39;t feel foreign, it&amp;#39;s just like being on yours but at a different desk.&lt;/p&gt;

&lt;p&gt;Most importantly though is that even though you&amp;#39;re both working on the same task together on the same machine, you&amp;#39;re probably both in slightly different head spaces and thinking about a slightly different aspect of the problem. Quickly switching between applications to satisfy your own curiosities can have a terrible impact on whatever it was your pair was thinking about. Being able to see everything at the one time prevents you from unexpectedly switching context on each other.&lt;/p&gt;

&lt;p&gt;Make sure you get a monitor large enough to make it work. Given you&amp;#39;re going to spend ~8 hours each and every day staring at it, it&amp;#39;s not sensible to buy a cheap screen.&lt;/p&gt;

&lt;h4&gt;Silence is golden&lt;/h4&gt;

&lt;p&gt;This is difficult to nail until you&amp;#39;ve developed a good working relationship with your pair, but the best communication between the two of you is the non-verbal. For the same reasons above, you can never be sure what the head space of your pair is and interrupting them to mention a typo could completely break their train of thought. Instead wait for an obvious pause or context switch and simply point it out. Eventually it may get to the point where you know each other well enough that even more subtle queues like a shift in posture give away that you need to re-think the code you just wrote. But at least you can then do it once you&amp;#39;ve got your current thoughts committed to screen.&lt;/p&gt;

&lt;h4&gt;80 characters is enough for anyone&lt;/h4&gt;

&lt;p&gt;Like many of the tips on here, they&amp;#39;ve either been passed on to me by &lt;a href=&quot;http://effectif.com/&quot;&gt;Graham Ashton&lt;/a&gt; or refined further by working with him for 3 years. This one seemed particularly pedantic to me, but I went along with it because it really wasn&amp;#39;t that difficult to adhere to and he was adamant that he&amp;#39;d accept nothing less. And it&amp;#39;s this, no line of code should ever extend beyond 80 characters.&lt;/p&gt;

&lt;p&gt;I now try to enforce it wherever I go.&lt;/p&gt;

&lt;p&gt;It took me a long time to fully appreciate how important it is, at least a year, but code readability is drastically improved and that is always a good thing. When pairing though, it is mandatory. You don&amp;#39;t have the luxury of scrolling indefinitely to the right to read the full line of code to see the intention because doing so will interrupt the flow of your pair. Worse still, it actually takes the bulk of the code off the screen.&lt;/p&gt;

&lt;p&gt;It also prevents a nasty scenario where something important that drastically changes the intention of a line of code is cleanly hidden by the window edge and the real flow of the application is the opposite of what you thought was happening. Say something like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def my_example_method&amp;#x000A;  raise &amp;quot;Here is an example of something you would think gets raised!!!&amp;quot; unless coder_reads_this_part?&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Refactor any line that stretches over 80 characters. It only requires a little thought, makes the intention clearer, ensures you can see all the important code at once, and stops you from having to break someone else&amp;#39;s focus.&lt;/p&gt;

&lt;h3&gt;Test Driven Development&lt;/h3&gt;

&lt;p&gt;Tests first, then the code. It&amp;#39;s not just about ensuring you&amp;#39;ve got stable and working code, it&amp;#39;s about keep focussed on doing the smallest thing possible to make the tests pass.&lt;/p&gt;

&lt;p&gt;This approach works great with pair programming, and here&amp;#39;s the formula: One person writes a test, the other makes it pass. Once it&amp;#39;s passing the person that just wrote the code writes the next test and hands it over. While one of you is trying to write a crafty test to keep the other busy for a while, your pair has already devised a cheeky way to have it always return the value you want and has devised a new test to catch you out. &lt;/p&gt;

&lt;p&gt;It&amp;#39;s generally a quick back and forth iterative process where you&amp;#39;re each trying to outfox the other with edge cases or overly simplistic implementations that pass because the tests are robust enough. It&amp;#39;s almost game-like, and eventually you both come to a stalemate. At that point you sit back and realise the story is complete, and with excellent test coverage.&lt;/p&gt;

&lt;h3&gt;Don&amp;#39;t break the build&lt;/h3&gt;

&lt;p&gt;A continuous integration server is a must as is some form of reporting of any errors raised in production, and problems on both must be treated with a suitably high priority. Anything that is deemed &amp;quot;flakey&amp;quot; and raises an alert for non-legitimate reasons needs to be fixed immediately. As soon as the team starts to doubt the notifications, legitimate problems start to slip through too. It&amp;#39;s a bit like the broken windows theory, if you allow these things to go by without action then it breeds complacency and soon some failing tests become accepted as the norm.&lt;/p&gt;

&lt;p&gt;That all means that before any developer commits any code back upstream, they run all the tests&amp;hellip; all the time. They are there for a reason, and it&amp;#39;s inexcusable to not be running them. The CI box is there as a backstop only.&lt;/p&gt;

&lt;h3&gt;Deliver at the beginning of the end&lt;/h3&gt;

&lt;p&gt;If you&amp;#39;re starting your iterations every second Wednesday then code needs to be completed at the close of play the Monday immediately prior. That means you&amp;#39;ve got a full day to deploy the code to production and catch any unexpected errors. The other benefit of the mid-week approach is that on the rare occasions it all goes pear-shaped people are more inclined to stay back a little late and fix it. Trying to keep people back after hours on a Friday isn&amp;#39;t just difficult, they&amp;#39;ve often already mentally checked out and off on their weekend and you run the risk of actually making a bad situation worse.&lt;/p&gt;

&lt;p&gt;If it all goes seamlessly and you roll-out and have a day free, fantastic! Time to look at that ever growing list of bugs your users have been sending back that haven&amp;#39;t been getting scheduled into an iteration. You can always find small tasks to fill the day that are incredibly useful but not super urgent.&lt;/p&gt;

&lt;p&gt;Avoid bringing planning and unscheduled work forward, you&amp;#39;ll skew your workload for the next iteration and run the risk of over-stressing developers and/or over committing. The benefit of &lt;em&gt;maybe&lt;/em&gt; squeezing in a day of development isn&amp;#39;t worth the additional risks.&lt;/p&gt;

&lt;h2&gt;Review&lt;/h2&gt;

&lt;p&gt;The code is released, people are using it, and everyone is happy. Now it&amp;#39;s time to look back and see how things went, what went really well and what could be improved upon.&lt;/p&gt;

&lt;h3&gt;Run a retrospective&lt;/h3&gt;

&lt;p&gt;Before the planning session, get all the team in the room to talk about the good and the bad of the previous iteration. Do it quickly, you should need an absolute max of 30mins but you can probably do it in much less. Get index cards or post-it notes of two different colours, one for &amp;quot;went well&amp;quot; and one for &amp;quot;needs improvement&amp;quot;, and everyone has to write at least one thing on a card of each colour. There are no limits to how many things people can list though, allow it as a cathartic forum for all issues to be brought out in the open.&lt;/p&gt;

&lt;p&gt;Put all the cards up on a board (grouping similar topics), so everyone can see the balance of opinion on how things went. Ensure everyone understands what all of the cards mean and what they are referring to. Now everyone gets 3 points to spend on the &amp;quot;needs improvement&amp;quot; cards, they can spread the points out across 3 cards or put them all onto a single card (or the obvious option in between). The 3 cards that have the most points the team agrees to make a concerted effort to improve upon during the next iteration.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s only after a couple of iterations with consistently re-appearing top rated problem that I&amp;#39;d consider going back at looking at some of the tools I mentioned throwing out at the top of this article. And even then, only if you&amp;#39;re certain they&amp;#39;re the best way to fix the most pressing issue facing your team. If I&amp;#39;m honest, I don&amp;#39;t think it&amp;#39;s going to come up.&lt;/p&gt;

&lt;h3&gt;Split partially-completed stories&lt;/h3&gt;

&lt;p&gt;Occasionally a story only gets partly done, and there is much gnashing of teeth when people have to work out what to do with it. Because you&amp;#39;ve been taking an iterative test driven development you&amp;#39;ve got a bunch of code that is written, tested, and passing even though the story is incomplete. Fantastic!&lt;/p&gt;

&lt;p&gt;Look at what is left to complete and write up a suitable story to reflect it, then go back and revise the previous card to reflect what was actually done. Now look at the original estimate and try and work out what percentage of the story you&amp;#39;ve completed, apply the appropriate number of points to each story (keeping in mind that if you&amp;#39;re following along with my 3 point/jelly bean system, 3 points = 2 days. So if you&amp;#39;ve done half you&amp;#39;ve got 1 day on each or 2 points on each).&lt;/p&gt;

&lt;p&gt;That way you get an accurate reflection of both what was completed in the previous iteration and a fair idea of what remains, based on your original estimates (remember, we wanted continual optimism. No revising estimates retrospectively).&lt;/p&gt;

&lt;h3&gt;Calculate your velocity&lt;/h3&gt;

&lt;p&gt;Now you know how much work you got completed, you can with a fair degree of confidence predict how much you can do next iteration. After a few iterations, you can look back and calculate the average for the past two or 3 to flatten out any particular fast or slow ones and get a good feel for what is achievable. &lt;/p&gt;

&lt;h3&gt;Under-promise, over-deliver&lt;/h3&gt;

&lt;p&gt;No kid likes waking up Christmas morning to find the present they asked Santa for to be nowhere under the tree. Likewise, no customer likes being told you&amp;#39;re going to give them something in two weeks and for it to not materialise. So if you&amp;#39;re uncertain, you&amp;#39;re better off scheduling too little work and then pulling an extra story in later in the iteration than over committing. It&amp;#39;s not just about managing customer expectations though, it&amp;#39;s about limiting stress on developers by keeping the targets realistic.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;These are the things that have contributed to making it work at places I&amp;#39;ve enjoyed working at. The most important thing is to measure overall success of your process as it&amp;#39;s ability to create a happy and productive environment, good things will naturally flow from it. At the very least you should apply the principles of agile to the implementation of the process itself. Nothing is set in stone, pause at regular intervals to review the success, adjust the most important aspects to give people what they want.&lt;/p&gt;</content>
    <published>2010-09-06T11:00:00+00:00</published>
    <updated>2010-09-06T11:00:00+00:00</updated>
    <category term='general'></category>
  </entry>
  <entry>
    <title>Nobody cares what tools you&nbsp;use</title>
    <link href='http://rubypond.com/blog/nobody-cares-what-tools-you-use' rel='alternate' type='text/html' />
    <id>tag:rubypond.com,2010-09-02:/blog/nobody-cares-what-tools-you-use</id>
    <content type='html'>&lt;p&gt;I&amp;#39;ve spent almost all of my career with something along the lines of &amp;quot;freelancer&amp;quot;, &amp;quot;consultant&amp;quot;, or &amp;quot;contractor&amp;quot; on my business cards and the forms HR departments make me sign. On the two occasions that hasn&amp;#39;t been the case I&amp;#39;ve been working for as part of a development team that was primarily developing solutions for external customers, or managing a team of contractors working on launching a start-up. So I&amp;#39;ve been really very fortunate to work across a really broad spectrum of clients and environments and with some brilliant people, which over time makes it easier to appreciate what works and what doesn&amp;#39;t.&lt;/p&gt;

&lt;h2&gt;You&amp;#39;re probably doing it&amp;nbsp;wrong&lt;/h2&gt;

&lt;p&gt;Coming into a new company is always interesting, no matter how wonderful the people or the environment there is always at least one aspect of their job that they don&amp;#39;t enjoy. More often that not it&amp;#39;s some process that has been enforced by management types who had the best of intentions, but didn&amp;#39;t appreciate the impact on those caught in the process. I&amp;#39;ve been that manager, I&amp;#39;ve implemented that process, and I apologise to those in the past that were affected by it.&lt;/p&gt;

&lt;p&gt;The worst manifestation of this is the implementation of &amp;quot;agile&amp;quot; at most places I&amp;#39;ve worked. What seems to happen is a progressive manager reads about the productivity gains and other benefits of being &amp;quot;more agile&amp;quot; and either implements it in a piecemeal fashion, picks and chooses the bits that makes the most sense, or thinks that somehow magically telling people to read the agile manifesto and crack to it will make it happen. Other times it&amp;#39;s a developer that wants to make everyones lives better and their company more productive but doesn&amp;#39;t have the authority to implement the changes alone. It&amp;#39;s the same end result.&lt;/p&gt;

&lt;p&gt;I&amp;#39;m going to follow this post with another on my tips for &amp;quot;&lt;a href=&quot;http://rubypond.com/blog/quickstart-guide-to-agile&quot;&gt;doing agile right&lt;/a&gt;&amp;quot;, and practices to generally avoid. I have to give credit however to &lt;a href=&quot;http://effectif.com/&quot;&gt;Graham Ashton&lt;/a&gt;, working closely with him for almost 3 years refined my understanding of how to do it properly and I hope he does a post of his own to cover anything I may miss. In the interim I&amp;#39;ll give you a secret to help you take the first step to salvation. Every time you go to write something, fill in some plan, have a meeting, or do anything mandated by your &amp;quot;process&amp;quot; ask yourself &amp;quot;is this going to make me deliver the product faster?&amp;quot;. If the answer is no, don&amp;#39;t do it.&lt;/p&gt;

&lt;h2&gt;You&amp;#39;re not there to write *insert language of choice&amp;nbsp;here*&lt;/h2&gt;

&lt;p&gt;I heard this explained best by Obie Fernandez during a Q&amp;amp;A session when someone asked how you convince customers that you&amp;#39;re not going to offer an upfront fixed-cost bid on some work. I&amp;#39;m paraphrasing here, but he essentially said that Hash Rocket customers don&amp;#39;t sign up for a project or deliverable but rather they engage Hash Rocket for their expertise and experience. Either you freelance or your an employee it&amp;#39;s the same thing, whoever has employed you hasn&amp;#39;t got you in to just cut code. They&amp;#39;ve assessed a whole range of your background and experience before moving forward with you, and they ultimately want to use that experience to their advantage and solve at least one problem they have. Whether you&amp;#39;re writing code in Java or Ruby or PHP is inconsequential, you make a judgement call on what is best for the business and what will allow you to get the job done most effectively given your experience. In some places, that means you have to fall in line with existing technologies because at the end of the day that is &amp;quot;best for the business&amp;quot;. Which brings me back to my original point&amp;hellip;&lt;/p&gt;

&lt;h2&gt;Nobody gives a damn about what tools you&amp;nbsp;use&lt;/h2&gt;

&lt;p&gt;And by nobody, I mean nobody outside the people who also have to use the tool(s) in question. A senior manager need not care if I&amp;#39;m writing Ruby or Python, using Rails, Django, or Sinatra. They&amp;#39;ve got a problem they need fixed, get it done as effectively as possible. My post yesterday about &lt;a href=&quot;http://rubypond.com/blog/you-dont-win-friends-with-salad&quot;&gt;the benefits of testing with cucumber&lt;/a&gt; is another example. I&amp;#39;ve worked in places where we&amp;#39;ve tried this approach, giving the customer the ability to see the output of the test suite (sometimes even letting them write the stories), being able to see as features one-by-one go from being red to green as the continuous integration box output the results of the latest commit to a nice website where everyone can see where we are. And then when everything goes green there is much rejoicing, clapping of hands, and popping of champagne.&lt;/p&gt;

&lt;p&gt;Except it never happens. The customer looks at the test output for a week, at best a month, and then stops caring. And why should they care? After &lt;em&gt;you&lt;/em&gt; write the story (more on that in the next post) &lt;em&gt;their&lt;/em&gt; interest in reading it ever again is almost zero. Whether or not you&amp;#39;ve ticked some boxes, made some text go green, or moved index cards from one end of a board to the other is of no importance to your customer. All they care about is working software. Delivered, working software. You can proclaim a &amp;quot;story&amp;quot; is finished until you are blue in the face they don&amp;#39;t truly believe you until they&amp;#39;ve played with it themselves and made sure it meets all their expectations, including the ones they forgot to tell you about.&lt;/p&gt;

&lt;h2&gt;A lot of tools are just getting in your way&lt;/h2&gt;

&lt;p&gt;So if your customer is never going to read your story, why go to the hassle of incorporating it into a core part of your workflow in a fashion that only serves to slow you down? And I&amp;#39;m not pointing the finger just at testing tools here, I&amp;#39;m putting almost any tool I&amp;#39;ve used that is trying to bridge the gap between developer and customer into the firing line. I&amp;#39;ve never found a project management tool that made me think &amp;quot;Wow! This is incredible, I&amp;#39;ll never work without this tool again&amp;quot; because they&amp;#39;re all basically shit, just some less shit than others (Mingle and Pivotal Tracker are reasonable). Even when I&amp;#39;ve been managing a team I&amp;#39;ve been less than enthused about using them, and I&amp;#39;m convinced that if you&amp;#39;re sharing a workspace with the others in your team that many of these tools offer no real benefit over far more simple and possibly less tech focussed solutions.&lt;/p&gt;

&lt;p&gt;Their worst crime though is duping people into thinking that they&amp;#39;re actually helping to foster an agile environment and workflow. If you look at the original manifesto and break it down, most tools are actually taking you further from the core principles.&lt;/p&gt;

&lt;p&gt;Sit down and speak to your customer and then go do some work. Question the value of anything that happens in between.&lt;/p&gt;</content>
    <published>2010-09-02T13:45:00+00:00</published>
    <updated>2010-09-02T13:45:00+00:00</updated>
  </entry>
  <entry>
    <title>You don't win friends with salad</title>
    <link href='http://rubypond.com/blog/you-dont-win-friends-with-salad' rel='alternate' type='text/html' />
    <id>tag:rubypond.com,2010-09-01:/blog/you-dont-win-friends-with-salad</id>
    <content type='html'>&lt;p&gt;The ruby (and in particular the rails) community has grown at a pretty rapid rate since I started using it. The smaller community carried with it many benefits for a newbie, fewer options and fewer opinions on how to do things. Today though new developers have to contend with outdated documentation and tutorials (although &lt;a href=&quot;http://guides.rubyonrails.org/&quot;&gt;http://guides.rubyonrails.org/&lt;/a&gt; and the official docs have gone to great effort at late to keep everything updated), a veritable smorgasbord of options for everything from database access to asset packaging, and an even greater number of vocal opinions on how you should be doing it all. When it comes to testing it would be easy to think that the jury has spoken; You should be using Cucumber, Webrat, and RSpec.&lt;/p&gt;

&lt;h2&gt;Improved readability&lt;/h2&gt;

&lt;p&gt;One of the benefits of cucumber is that suddenly tests aren&amp;#39;t written in ruby or any other language any more they&amp;#39;re in plain text, and readable English text at that! And who can&amp;#39;t read English? Let&amp;#39;s take an example from &lt;a href=&quot;http://elabs.se/blog/15-you-re-cuking-it-wrong&quot;&gt;Jonas Nicklas&lt;/a&gt; (let me also point out, Jonas has done a great job at pointing out where I think a lot of cuke practitioners get it fundamentally wrong&amp;hellip; go read it):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Scenario: Adding a subpage&amp;#x000A;  Given I am logged in&amp;#x000A;  Given a microsite with a home page&amp;#x000A;  When I press &amp;quot;Add subpage&amp;quot;&amp;#x000A;  And I fill in &amp;quot;Title&amp;quot; with &amp;quot;Gallery&amp;quot;&amp;#x000A;  And I press &amp;quot;Ok&amp;quot;&amp;#x000A;  Then I should see a document called &amp;quot;Gallery&amp;quot;&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Contrast that to some plain ol&amp;#39; ruby and the standard Webrat syntax (using shoulda):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;context &amp;quot;logged in user&amp;quot;&amp;#x000A;  should &amp;quot;be able to add a subpage&amp;quot; do&amp;#x000A;    visit homepage&amp;#x000A;    click &amp;quot;Add subpage&amp;quot;&amp;#x000A;    fill_in &amp;quot;Title&amp;quot;, :with =&amp;gt; &amp;quot;Gallery&amp;quot;&amp;#x000A;    click &amp;quot;Ok&amp;quot;&amp;#x000A;    assert_have_selector &amp;quot;.documents&amp;quot; do&amp;#x000A;      assert_contain(&amp;quot;Gallery&amp;quot;)&amp;#x000A;    end&amp;#x000A;  end&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or if you want to refactor that last assertion into a helper method/macro:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;context &amp;quot;logged in user&amp;quot;&amp;#x000A;  should &amp;quot;be able to add a subpage&amp;quot; do&amp;#x000A;    visit homepage&amp;#x000A;    click &amp;quot;Add subpage&amp;quot;&amp;#x000A;    fill_in &amp;quot;Title&amp;quot;, :with =&amp;gt; &amp;quot;Gallery&amp;quot;&amp;#x000A;    click &amp;quot;Ok&amp;quot;&amp;#x000A;    assert_has_document(&amp;quot;Gallery&amp;quot;)&amp;#x000A;  end&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now go back and read the first cucumber example, and the final shoulda/webrat example. Do it again. Is there any appreciable difference in readability? I&amp;#39;m confident I could put the latter in front of my non-tech involved fiancé and she&amp;#39;d be able to tell me what it&amp;#39;s trying to do, but I&amp;#39;ll discuss if that is even important later. The simple fact is that any ruby developer is going to be able to derive intention just as easily from both snippets of code.&lt;/p&gt;

&lt;h2&gt;Layers of indirection&lt;/h2&gt;

&lt;p&gt;Like an accomplished magician, cucumbers real trick is to have you looking somewhere other than where the magic is really happening. Open up a feature file and you&amp;#39;ll be greeted by something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Scenario: Concealing behind a wall of smoke and mirros&amp;#x000A;  When I ask cucumber to run a scenario&amp;#x000A;  And I add 5 to 2 for a contrived step&amp;#x000A;  Then the scenario should have completed&amp;#x000A;  And it should add up to 7&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Great, you know the intention behind this particular feature. But where do we go to find the steps for this test? Well there is obviously the steps file(s), but in a large project there are probably a few so which one? Say we&amp;#39;ve found the right file, how do you find the line responsible? You can&amp;#39;t simply do a search for &amp;quot;ask cucumber to run a scenario&amp;quot; because the actual step definitions probably look something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;When /^I ask ([a-z]+) to run a ([a-z]+)$/ do |framework,granularity|&amp;#x000A;  # do stuff&amp;#x000A;end&amp;#x000A;When /^I add ([0-9]+) to ([0-9]+) for a contrived step$/ do |a,b|&amp;#x000A;  # do stuff&amp;#x000A;end&amp;#x000A;Then /^the ([a-z]+) should have completed$/ do |granularity|&amp;#x000A;  # do stuff&amp;#x000A;end&amp;#x000A;Then /^it should add up to ([0-9]+)$/ do |result|&amp;#x000A;  # do stuff&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Basically unless you already know the signature of the various methods you&amp;#39;ve got two options: 1) Read the whole damn file or 2) Run the features with verbose output so you can see which line gets invoked in your step file(s).&lt;/p&gt;

&lt;p&gt;It&amp;#39;s not an insurmountable problem, but it does present an additional barrier to understanding the code. And as I pointed out in the previous section, for a negligible gain given you can write plain ruby with the intention being just as clear. The benefit of that approach is that the plain ol&amp;#39; ruby isn&amp;#39;t just your intention, it&amp;#39;s actually the code that gets executed. There isn&amp;#39;t an additional layer of comprehension required to see where the work is getting done, and if I&amp;#39;ve written a custom method/matcher/macro then I can actually search for it because it&amp;#39;s immediately obvious what the name of that method is.&lt;/p&gt;

&lt;h2&gt;It&amp;#39;s not actually English!&lt;/h2&gt;

&lt;p&gt;And here&amp;#39;s my real issue with all those people drowning themselves in the cucumber kool-aid: they&amp;#39;re convinced that this extra layer makes the intention of the application clear, that &amp;quot;the business&amp;quot; has visibility of what the product can do, and everybody is on the same page with regards to scope. If any of those have been a problem for you or your team writing it all down in a prescribed faux-English format isn&amp;#39;t going to magically solve your problems. You need to sit down with your client/&amp;quot;the business&amp;quot; and actually engage with them, stop listening to them tell you what they want, and become involved enough to extract what it is they actually need.&lt;/p&gt;

&lt;p&gt;I think the worst possible situation you can be in is thinking that at some point clients will be able to write the cucumber features themselves and you can focus on just making them pass. You&amp;#39;ve now forced upon them a foreign and limited grammar in which they are going to try and define the scope of their problems, and you&amp;#39;ve taken yourself out of the loop of truly understanding what the real nature of what you&amp;#39;re building for the client is. (I discussed this further in my post: &lt;a href=&quot;http://rubypond.com/blog/nobody-cares-what-tools-you-use&quot;&gt;Nobody cares what tools you use&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The end result is you&amp;#39;ve both compromised and come to a middle ground that is less than optimal for both parties&amp;hellip; and it takes a particularly skilled and dedicated developer (and a lot of work) to stop that being reflected in the quality of the delivered product.&lt;/p&gt;

&lt;h2&gt;How to do it better&lt;/h2&gt;

&lt;p&gt;If you&amp;#39;re a one person dev team, you need to seriously ask yourself if you would derive &lt;em&gt;any&lt;/em&gt; benefit from the indirection added by using cucumber? Will it improve the maintainability of your code? Your development velocity? Your ability to engage with your clients? The quality of the product you deliver? If you&amp;#39;re part of a larger company and it sounds like cucumber will fix a lot of problems you&amp;#39;ve been suffering, I&amp;#39;ll follow this up with a post arguing that most of it can probably be fixed by refocussing on &lt;a href=&quot;http://rubypond.com/blog/quickstart-guide-to-agile&quot;&gt;doing agile properly&lt;/a&gt;.&lt;/p&gt;</content>
    <published>2010-09-01T10:00:00+00:00</published>
    <updated>2010-09-01T10:00:00+00:00</updated>
    <category term='ruby-on-rails'></category>
  </entry>
  <entry>
    <title>Github-style capistrano deployments</title>
    <link href='http://rubypond.com/blog/github-style-capistrano-deployment' rel='alternate' type='text/html' />
    <id>tag:rubypond.com,2010-08-26:/blog/github-style-capistrano-deployment</id>
    <content type='html'>&lt;p&gt;If you&amp;#39;ve deployed a rails app the chances are high that you&amp;#39;ve done it using capistrano. Capistrano has come a long way, but it was originally designed back when we were all using svn to manage our code. Times have changed, and we can make some significant improvements to the default process.&lt;/p&gt;

&lt;h2&gt;Credit where credit is due&lt;/h2&gt;

&lt;p&gt;First, I can&amp;#39;t take the credit for this refactor of the capistrano deployment scripts. That honour goes to Chris @ GitHub, and he has a &lt;a href=&quot;http://github.com/blog/470-deployment-script-spring-cleaning&quot;&gt;great explanation&lt;/a&gt; of what he did and why over on their blog.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve been using this style of deployment on all my projects since Chris announced it, but there are some things I needed which were supported by either capistrano natively or by these new additions.&lt;/p&gt;

&lt;h2&gt;Setting up your web server configuration&lt;/h2&gt;

&lt;p&gt;I almost always deploy to an nginx server running passenger, apache is a rarity these days. In any event I&amp;#39;ve made an assumption that both servers will be setup to dynamically include their virtual host config files from a specific location. As a result, running &lt;code&gt;cap deploy:setup&lt;/code&gt; will not also create the appropriate config file for your server and restart apache/nginx. You can set the &lt;code&gt;nginx_conf_dir&lt;/code&gt; or &lt;code&gt;apache_conf_dir&lt;/code&gt; to specify the appropriate place to put the file. Take a look at &lt;code&gt;config/deploy/apache.rb&lt;/code&gt; and &lt;code&gt;config/deploy/nginx.rb&lt;/code&gt; for the respective configuration templates.&lt;/p&gt;

&lt;h2&gt;Moving all application settings to a common place&lt;/h2&gt;

&lt;p&gt;Common application settings have all been moved to &lt;code&gt;config/deploy/settings.rb&lt;/code&gt;, so this will include things like your application name, source control system (this approach only supports git) and repository location. You&amp;#39;ll need to change things in this file to be relevant to your own application.&lt;/p&gt;

&lt;h2&gt;Deploying to different target environments&lt;/h2&gt;

&lt;p&gt;I&amp;#39;ll usually have more than one environment I want to deploy the code to (production, staging, demo, etc.), and cap has a built in means of handling this&amp;hellip; you don&amp;#39;t need to go install some extra gem or plugin. Each target is defined in &lt;code&gt;config/deploy/targets.rb&lt;/code&gt;, and example of definition is as following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    task :production do&amp;#x000A;      role :web, [&amp;quot;192.168.1.10&amp;quot;, &amp;quot;192.168.1.11&amp;quot;]&amp;#x000A;      role :app, [&amp;quot;192.168.1.10&amp;quot;, &amp;quot;192.168.1.11&amp;quot;]&amp;#x000A;      role :db,  &amp;quot;192.168.1.12&amp;quot;, :primary =&amp;gt; true&amp;#x000A;      set :web_server, :nginx&amp;#x000A;      set :web_port, &amp;quot;80&amp;quot;&amp;#x000A;    end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This file is for any settings that will vary from machine-to-machine or between environments. Anything that is going to be the same on every machine belongs in &lt;code&gt;config/deploy/settings.rb&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;How to get started&lt;/h2&gt;

&lt;p&gt;Go take a look at &lt;a href=&quot;http://github.com/rubypond/git-based-deploy&quot;&gt;Git-based-deploy&lt;/a&gt; GitHub repository, grab the code and get deploying. Submit me any patches if you find problems or think of something worth including.&lt;/p&gt;</content>
    <published>2010-08-26T10:00:00+00:00</published>
    <updated>2010-08-26T10:00:00+00:00</updated>
  </entry>
  <entry>
    <title>Don't put your private key on a public server</title>
    <link href='http://rubypond.com/blog/dont-put-your-private-key-on-a-public-server' rel='alternate' type='text/html' />
    <id>tag:rubypond.com,2010-08-25:/blog/dont-put-your-private-key-on-a-public-server</id>
    <content type='html'>&lt;p&gt;You&amp;#39;re administering a server (Server A), and you need access to something on another server (Server B) but access is denied from Server A because you don&amp;#39;t have your private key on there. If this is a scenario you&amp;#39;ve run into while trying to deploy an application it&amp;#39;s almost certain that you don&amp;#39;t want to put your private key on the server in the home directory of your deployment user, readable to anyone that can log in as that account (i.e, people other than you!).&lt;/p&gt;

&lt;h2&gt;SSH Agent Forwarding to the rescue&lt;/h2&gt;

&lt;p&gt;To get around this SSH has built in support for forwarding on your private credentials. What happens is that when you connect to a remote server the &lt;code&gt;ssh-agent&lt;/code&gt; creates a unix socket and then listens to connections from &lt;code&gt;ssh&lt;/code&gt;, this socket is accessible only by your user account&amp;hellip; and root.&lt;/p&gt;

&lt;p&gt;Yes, what this in fact means is that the root user on the remote server has access to the unix socket you&amp;#39;ve created. They can&amp;#39;t see your private keys, they&amp;#39;re still safely held on your client, but while you&amp;#39;re connected to the remote server the root user on that machine could potentially use that socket to connect as you to another server. In short, make sure you trust root before you set this up (still, it&amp;#39;s better than putting your private key in your home directory where root would now be able to see they key and use it whenever they wanted).&lt;/p&gt;

&lt;h2&gt;Configure your SSH client to use Agent Forwarding&lt;/h2&gt;

&lt;p&gt;Getting it to work is as simple as adding an entry to &lt;code&gt;~/.ssh/config&lt;/code&gt; (create the file if it doesn&amp;#39;t exist):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Host remote-server.example.com&amp;#x000A;  ForwardAgent yes&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Just replace the Host value with the hostname or IP address of the server you are connecting to, or with &lt;code&gt;*&lt;/code&gt; if you&amp;#39;re brave and want to do it automatically for all hosts.&lt;/p&gt;

&lt;h2&gt;Restarting your local SSH Agent&lt;/h2&gt;

&lt;p&gt;On my Macbook Pro I&amp;#39;ve added the following to my &lt;code&gt;~/.bash_profile&lt;/code&gt; to make sure that the SSH Agent is started when I open a new terminal and that my identities (private keys) are added to it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    SSH_ENV=$HOME/.ssh/environment&amp;#x000A;&amp;#x000A;    function start_agent {&amp;#x000A;         echo &amp;quot;Initializing new SSH agent...&amp;quot;&amp;#x000A;         /usr/bin/ssh-agent | sed &amp;#39;s/^echo/#echo/&amp;#39; &amp;gt; ${SSH_ENV}&amp;#x000A;         echo succeeded&amp;#x000A;         chmod 600 ${SSH_ENV}&amp;#x000A;         . ${SSH_ENV} &amp;gt; /dev/null&amp;#x000A;         /usr/bin/ssh-add;&amp;#x000A;    }&amp;#x000A;&amp;#x000A;    if [ -f &amp;quot;${SSH_ENV}&amp;quot; ]; then&amp;#x000A;         . ${SSH_ENV} &amp;gt; /dev/null&amp;#x000A;         ps -x | grep &amp;quot;^ *${SSH_AGENT_PID}&amp;quot; | grep ssh-agent$ &amp;gt; /dev/null || {&amp;#x000A;             start_agent;&amp;#x000A;         }&amp;#x000A;    else&amp;#x000A;         start_agent;&amp;#x000A;    fi&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;</content>
    <published>2010-08-25T14:30:00+00:00</published>
    <updated>2010-08-25T14:30:00+00:00</updated>
  </entry>
  <entry>
    <title>Getting started with MongoDB</title>
    <link href='http://rubypond.com/blog/getting-started-with-mongodb' rel='alternate' type='text/html' />
    <id>tag:rubypond.com,2010-07-03:/blog/getting-started-with-mongodb</id>
    <content type='html'>&lt;p&gt;MongoDB is a document database, which if you&amp;#39;ve not come across before is best visualised as a way of persisting a complex Hash object. It varies from a key-value store (like memcache and redis) as the &amp;quot;documents&amp;quot; you store aren&amp;#39;t retrieved by their key alone, but can be extracted by querying the values. The objects can be of any structure as you don&amp;#39;t define a schema upfront, and can be nested to an infinite depth. &lt;/p&gt;

&lt;p&gt;The beauty in a design like this is that you can have a flexible way of storing whatever you want, with all dependent objects nested within each other so you don&amp;#39;t need to join across multiple tables to get the information you need. In situations where the most often use-case requires more than one query or a table join to retrieve everything you want (a blog post along with a series of comments is a good example) this can be a real performance win. You&amp;#39;d actually store the comments within the blog post itself rather than in a separate table or collection.&lt;/p&gt;

&lt;p&gt;Where I&amp;#39;ve found it useful, is in storing the data from the Twitter Streaming API. I&amp;#39;ve had grand plans to build an app on top of this data and API, but life continues to get in the way and in the interim period Twitter keeps adding new features and richer data. Thanks to MongoDB I don&amp;#39;t need to update my code to stay in step with their change, I just dump the data straight into the DB and it will automatically include the new fields that have been included. Even better, is that I can write queries against this new data immediately and don&amp;#39;t have to worry about migrations.&lt;/p&gt;

&lt;h2&gt;Installing MongoDB&lt;/h2&gt;

&lt;p&gt;Installing MongoDB is easy. On OSX I just used &lt;a href=&quot;http://mxcl.github.com/homebrew/&quot;&gt;Homebrew&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;brew install mongodb&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On other platforms there are binaries &lt;a href=&quot;http://www.mongodb.org/downloads&quot;&gt;available to download&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By default &lt;code&gt;mongod&lt;/code&gt; wants to store data in the &lt;code&gt;/data/db&lt;/code&gt; directory so you&amp;#39;ll need to create that first:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir -p /data/db&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once that&amp;#39;s done you can start the service by just running &lt;code&gt;mongod&lt;/code&gt;. Open another terminal session and run &lt;code&gt;mongo&lt;/code&gt; to connect to your local server. You&amp;#39;ll be taken to a Mongo shell session where you can start issuing Javascript commands to talk to your database. So start by doing the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;db.mydatabase.save({ name: &amp;quot;Steve&amp;quot; })&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The command above with save the document &lt;code&gt;{name: &amp;quot;Steve&amp;quot;}&lt;/code&gt; into the database called &lt;code&gt;mydatabase&lt;/code&gt;. But that doesn&amp;#39;t exist, does it? Well, it does now. If you try and issue a command to a database that doesn&amp;#39;t exist, Mongo will create the database for you and then run the command against it. If you take a look in &lt;code&gt;/data/db&lt;/code&gt; now you should see a couple of files, one of them is probably in the range of 64MB to 2GB. Hang about, what?! 2GB to store that one small document?&lt;/p&gt;

&lt;p&gt;Mongo will pre-allocate disk for storing these objects, that means the next record you insert wont increase the size of these files. It will continue appending documents into these pre-allocated files until they are full, at which point it will pre-allocate another file of the same size and repeat the process.&lt;/p&gt;

&lt;h2&gt;Storing the Twitter Stream in MongoDB&lt;/h2&gt;

&lt;p&gt;As I said, I&amp;#39;ve been using it as a flexible store for persisting the Twitter stream. I&amp;#39;ve created a &lt;code&gt;Tweet&lt;/code&gt; model to store each tweet that looks like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;mongo&amp;#39;&amp;#x000A;require &amp;#39;twitter-text&amp;#39;&amp;#x000A;&amp;#x000A;class Tweet  &amp;#x000A;  def self.create!(tweets)&amp;#x000A;    collection.insert(tweets)&amp;#x000A;  end&amp;#x000A;&amp;#x000A;  private&amp;#x000A;    def self.establish_connection&amp;#x000A;      Mongo::Connection.new.db(&amp;quot;twitter&amp;quot;)&amp;#x000A;    end&amp;#x000A;&amp;#x000A;    def self.db&amp;#x000A;      @db ||= establish_connection&amp;#x000A;    end&amp;#x000A;&amp;#x000A;    def self.collection&amp;#x000A;      @collection ||= db.collection(&amp;quot;tweets&amp;quot;)&amp;#x000A;    end&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&amp;#39;m just using the native ruby driver and not using one of the wrapper libraries, and to be honest I have no plans to as the interface is so simple I don&amp;#39;t really see the point. You just need to open a connection to a database (in this code above it&amp;#39;s called &lt;code&gt;twitter&lt;/code&gt;) and then identify the collection this model is writing to (the equivalent of a table for those transitioning from SQL, above it&amp;#39;s called &lt;code&gt;tweets&lt;/code&gt;). Remember that if the database and collection doesn&amp;#39;t exist, Mongo will just make it for us. Using the ruby code we&amp;#39;ve been building on from previous posts, we can take the data we&amp;#39;ve been receiving and store it with the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Twitter.stream(&amp;quot;mytwittername&amp;quot;, &amp;quot;secret&amp;quot;) do |status|&amp;#x000A;  Tweet.create!(status)&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Simple! Now you&amp;#39;re storing the tweets as quickly as they are arriving. That in itself isn&amp;#39;t very interesting though, so lets see how we&amp;#39;d go about retrieving some of our saved data.&lt;/p&gt;

&lt;h2&gt;Querying in MongoDB&lt;/h2&gt;

&lt;p&gt;To do the equivalent of a &lt;code&gt;select * from where ...&lt;/code&gt; in Mongo you need to pass a JSON object to the &lt;code&gt;find&lt;/code&gt; command. Something like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;collection.find(:user =&amp;gt; { :screen_name =&amp;gt; &amp;quot;glenngillen&amp;quot; })&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What might not be entirely obvious here is that the Twitter data comes back in a format like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{ :user =&amp;gt; { :screen_name =&amp;gt; &amp;quot;glenngillen&amp;quot;, &amp;#x000A;             :profile_image_url =&amp;gt; &amp;quot;http://rubypond.com/image.png&amp;quot;,&amp;#x000A;             :followers_count =&amp;gt; 1000000 },&amp;#x000A;  :text =&amp;gt; &amp;quot;This is the text from my tweet&amp;quot;&amp;#x000A;}&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And you can see from the query above, I&amp;#39;m able to query based on value nested down within the &lt;code&gt;:user&lt;/code&gt; key. Much like SQL, you can write queries to return data that is &lt;code&gt;in&lt;/code&gt; a given list of values, is greater than or less than a certain value, you can even match based on a regular expression. For more examples of how to query the data, head over to the &lt;a href=&quot;http://www.mongodb.org/display/DOCS/Advanced+Queries&quot;&gt;MongoDB query documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Taking it further&lt;/h2&gt;

&lt;p&gt;In coming posts I&amp;#39;ll expand on the previous examples, show you how to easily: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;filtering-the-twitter-streaming-api&quot;&gt;Supply additional options to the stream to filter it down to just the tweets you are interested in&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;getting-started-with-mongodb&quot;&gt;Setup &lt;code&gt;MongoDB&lt;/code&gt; to store the data you need&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Provision &lt;code&gt;Amazon EC2&lt;/code&gt; instances to help you deal with processing load&lt;/li&gt;
&lt;li&gt;Get &lt;code&gt;Chef&lt;/code&gt; involved to handle the provision and setup of your &lt;code&gt;EC2&lt;/code&gt; instances automatically&lt;/li&gt;
&lt;li&gt;Use RabbitMQ to dispatch work to multiple servers&lt;/li&gt;
&lt;li&gt;Load balance your &lt;code&gt;MongoDB&lt;/code&gt; instances across &lt;code&gt;EC2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
    <published>2010-07-03T00:00:00+00:00</published>
    <updated>2010-07-03T00:00:00+00:00</updated>
  </entry>
  <entry>
    <title>Managing email lists with Mailchimp and MonkeyWrench</title>
    <link href='http://rubypond.com/blog/managing-lists-with-mailchimp' rel='alternate' type='text/html' />
    <id>tag:rubypond.com,2010-07-02:/blog/managing-lists-with-mailchimp</id>
    <content type='html'>&lt;p&gt;Most of my projects and clients have a need to send email to the users to inform them of updates to the system, inform them of special marketing offers, or other such broadcast messages. Unfortunately, these type of messages can flag up warnings with many mail servers as your message may never arrive at the recipient. There are numerous providers out there that do what they can to make it easier, and most do a respectable job (I think I&amp;#39;ve used almost all of them at some stage). &lt;a href=&quot;http://www.mailchimp.com/&quot;&gt;Mailchimp&lt;/a&gt; (or &lt;a href=&quot;http://eepurl.com/Ge71&quot;&gt;here via an affiliate link&lt;/a&gt;) has proven to be the best for my purposes to date.&lt;/p&gt;

&lt;p&gt;They have a really rich and well documented API, a pretty good admin interface (although the bar is set pretty low here by most competitors), and they&amp;#39;re free to use until you get over 500 users. And even then they&amp;#39;re pretty good value for what you get.&lt;/p&gt;

&lt;h2&gt;Introducing MonkeyWrench&lt;/h2&gt;

&lt;p&gt;Over a year ago now I started first started integrating my apps to using Mailchimp, and while it was quite easy I did occasionally run into problems. The ruby APIs were just thin layer atop the Mailchimp API and it didn&amp;#39;t feel natural, plus there were a range of edge cases that were non-obvious unless you were hanging out in the dev forums or using the API &lt;em&gt;a lot&lt;/em&gt; (like the fact that you can&amp;#39;t batch subscribe members to a list &lt;em&gt;and&lt;/em&gt; send them a welcome email).&lt;/p&gt;

&lt;p&gt;So I wrote MonkeyWrench to overcome these shortcomings. It feels more natural to use within a ruby app, and it will automatically process large actions in batches, subscribe members as a list in batch if possible but do them individually if that is what is required. It&amp;#39;s all an attempt to make interacting with with your users as simple as possible.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s in production use for a number of clients, and significant portions of the codebase have been contributed/improved upon by &lt;a href=&quot;http://davidheath.org/&quot;&gt;David Heath&lt;/a&gt; who I&amp;#39;ve been working with at &lt;a href=&quot;http://www.wordtracker.com/&quot;&gt;Wordtracker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To give an example of how to use it, I&amp;#39;m going to just paste some of the README in here.&lt;/p&gt;

&lt;h2&gt;Getting Started&lt;/h2&gt;

&lt;p&gt;To get started, you need to first connect to the appropriate datacenter with your API key:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;MonkeyWrench::Config.new(:datacenter =&amp;gt; &amp;quot;us1&amp;quot;, &amp;#x000A;                         :apikey =&amp;gt; &amp;quot;your-api-key-goes-here&amp;quot;)&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;From there you&amp;#39;ve got a rich API for managing Lists and Members. To subscribe a new user to a list simply do the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;list = MonkeyWrench::List.find_by_name(&amp;quot;My Example List&amp;quot;)&amp;#x000A;list.subscribe(&amp;quot;foo@bar.com&amp;quot;)&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Taking it Further&lt;/h2&gt;

&lt;p&gt;Code is &lt;a href=&quot;http://github.com/rubypond/monkeywrench&quot;&gt;available at GitHub&lt;/a&gt;, &lt;a href=&quot;http://rdoc.info/projects/rubypond/monkeywrench&quot;&gt;documentation is an evolving affair&lt;/a&gt; (all of the List methods are documented). I&amp;#39;m more than happy to receive patches for any functionality that isn&amp;#39;t covered, we&amp;#39;ve only really implemented what we&amp;#39;ve needed to date. Just fork it, make a test, and send me a pull request with the patch.&lt;/p&gt;</content>
    <published>2010-07-02T00:00:00+00:00</published>
    <updated>2010-07-02T00:00:00+00:00</updated>
    <category term='ruby'></category>
  </entry>
</feed>

<!-- page cached: 2022-25-09 13:03:36 -->

