<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;Dk4FQX88fip7ImA9WhRVGE8.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190</id><updated>2012-01-17T18:28:30.176Z</updated><category term="linq" /><category term="iis" /><category term="wiki" /><category term="tools" /><category term="javascript" /><category term="movies" /><category term="patterns" /><category term="howto" /><category term="codegen" /><category term="random" /><category term="altnet" /><category term="humour" /><category term="community" /><category term="ffmpeg" /><category term="events" /><category term="titanium" /><category term="sagepay usability design" /><category term="html usability rant" /><category term="x-box 360" /><category term="rest" /><category term="mvc" /><category term="c#" /><category term="video encoding" /><category term="typography" /><category term="moq" /><category term="css" /><category term="classic-asp" /><category term="agile" /><category term="sql" /><category term="coding" /><category term="castle" /><category term="asp.net" /><category term="windows7" /><category term="sagepay agile tdd" /><category term="webdev" /><category term="musings" /><category term="usability" /><category term="confluence" /><category term="x64" /><category term="nhibernate" /><category term="hardware" /><category term="subversion" /><title>Dylan Beattie's Blog</title><subtitle type="html">Specs 'n' Bugs 'n' Rock 'n' Roll</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://dylanbeattie.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/14316836613796674016</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_LV_l8kYLOwo/SQ92E05MsMI/AAAAAAAAAGo/LcZtJuq7Fno/s1600-R/dylanbeattie.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>116</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/dylanbeattie" /><feedburner:info uri="dylanbeattie" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;AkMNQn0zfCp7ImA9WhdaFk8.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-7097102343786919271</id><published>2011-10-26T00:52:00.001+01:00</published><updated>2011-10-26T12:28:13.384+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-26T12:28:13.384+01:00</app:edited><title>GiveCamp UK 2011 – A Retrospective</title><content type="html">&lt;p&gt;I spent this last weekend at UCL’s Bloomsbury campus in London, with a hundred or so charitable geeks, at the first UK GiveCamp. I came away from it amazed – at the generosity of the volunteers and sponsors alike; at the sophistication of some of the solutions that were delivered within a single weekend, and at the reactions from the charities involved when we presented our projects on Sunday afternoon. It was a wonderful experience, and one I’d happily do again, but in the spirit of agile and continuous improvement, here’s my own personal retrospective on GiveCamp UK 2011.&lt;/p&gt;  &lt;h3&gt;What went well?&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;The project. I was lucky enough to be working with a team who were helping &lt;a href="http://www.sceneandheard.org/"&gt;Scene and Heard&lt;/a&gt;, a mentoring project based in north London that arranges for children to work with volunteer theatre professionals to write and perform plays. Simma , their Head of Development, showed up on Friday with a great pitch, obvious enthusiasm, a wealth of knowledge about the domain, and a “wish list” of projects and ideas for us to investigate. Top of the list was a ticket booking system – and I was immensely heartened when our entire team of coders – you know, people who like to &lt;em&gt;build&lt;/em&gt; stuff – unanimously agreed that the pragmatic solution would be to hook them up with &lt;a href="http://www.eventbrite.com/"&gt;EventBrite&lt;/a&gt;. By 8pm on Friday, we’d drawn up a backlog of requirements, made sure EventBrite would actually deliver what they needed, and a couple of the team were already working on the integration. This left the rest of us free to start looking at some of the more blue-sky ideas on Simma’s list… and somehow by Saturday afternoon we were building a full relational database, MVC web front-end, and a set of data migration and normalisation routines to import their data from a collection of Access and Excel sheets into SQL Server. It’s not quite live yet – we’re having some problems getting the Entity Framework config code to work with &lt;a href="http://www.appharbor.com/"&gt;AppHarbor&lt;/a&gt;’s SQL Server databases – but by the end of the week we hope to have it online, hosted, and handed over to them, for immediate use, or as a solid platform for future development. &lt;/li&gt;    &lt;li&gt;The venue. The power worked. There was ample desk space and seating. The wi-fi was pretty solid – for most of the weekend we were actually using their wi-fi network for all our database access and development, as well as simple web browsing &amp;amp; e-mail, and other than an occasional IP address change, it worked. &lt;/li&gt;    &lt;li&gt;The catering. The food was excellent, there were ample supplies of drinks, snacks, awesome tea thanks to &lt;a href="http://www.teapigs.co.uk/"&gt;Teapigs&lt;/a&gt;, fresh fruit and enough Haribo to keep you wired and coding well into the small hours. Result. &lt;/li&gt;    &lt;li&gt;The wrap-up. Without Paul &amp;amp; Phil imposing a strict code cut-off, we’d have happily coded until they threw us out – but in retrospect, having a hard deadline with plenty of notice really focused our efforts towards the end of the project. &lt;/li&gt;    &lt;li&gt;The platforms. We used &lt;a href="http://www.github.com/"&gt;Github&lt;/a&gt; for hosting, &lt;a href="https://trello.com/"&gt;Trello&lt;/a&gt; for organising our backlogs and a whole lot more besides; EventBrite solved the ticketing problem, and we’re in the process of deploying to AppHarbor. All fantastic, powerful tools – and all completely free. &lt;/li&gt;    &lt;li&gt;The swag. 80Gb SSDs for all the attendees? Best. Swag. EVER. Plus a hugely generous range of licenses, software, books and ebooks. Check out the list of sponsors at &lt;a href="http://www.givecamp.org.uk/sponsors"&gt;http://www.givecamp.org.uk/sponsors&lt;/a&gt; – I’m hugely grateful to every single one of them for making this amazing event a reality. &lt;/li&gt;    &lt;li&gt;The people. Everyone was helpful, cooperative, collaborative and enthusiastic, and I hope everyone learned as much working with each other as I did working with them. &lt;/li&gt;    &lt;li&gt;The demos. I was really, really impressed at what the teams delivered. From discovery to implementation to – in some cases – deployment onto a live website, in under 48 hours… as Ben Hall put it, it “makes you wonder what we normally &lt;em&gt;do&lt;/em&gt; all day…” I am also not at all biased by how genuinely delighted Simma and Jasmine looked when we showed them our work. Honest. &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;What could have gone better?&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;I thought the Friday start was too early. Lots of people – including several of the charities and one of the organisers – were held up in transit and missed the opening pitches and kick-off. The only downside of a venue as wonderfully accessible as UCL Bloomsbury is that at 5pm on a Friday it’s smack in the middle of the worst rush hour in the country. Just an idea – but I’d suggest next time a preliminary session, maybe earlier in the week, with the team leaders and the charity reps? A solid couple of hours capturing requirements and understanding the domain. We’d have been up to speed much quicker if one or two of us had had the chance to think things over ahead of time. &lt;/li&gt;    &lt;li&gt;That’s actually the only criticism I have of the event itself. The rest are memos to myself and the team for next time:      &lt;ul&gt;       &lt;li&gt;Bring an ergonomic keyboard! By Sunday afternoon my arms were starting to seize up… I’m not a laptop coder by choice, and having one of my trusty MS Natural 4000s would have made a *huge* difference. Plus a proper mouse. And a second monitor. &lt;/li&gt;        &lt;li&gt;Stick to what you know. This is not an event for trying out new technology – unless someone on your team knows it well, don’t go near it. We spent a good half-day investigating Visual Studio Lightswitch before concluding that we just didn’t have the expertise to tailor it to our requirements… it was gone 3pm on Saturday when we finally settled on ASP.NET MVC 3 with Entity Framework, and an hour later we were absolutely &lt;em&gt;flying&lt;/em&gt;. &lt;/li&gt;        &lt;li&gt;Get a Skype chat or IRC channel set up ASAP. You’re going to be sharing lots of addresses, API keys, URLs – stuff that’s time-consuming to read out loud or write on paper. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In conclusion – wonderful event, I’m really pleased to have been part of it, and I hope the rest of our team will be at the next one because I’d love to work with them again some time. And huge thanks to Paul Stack, Rachel Hawley, Phil Winstanley, Kendal Miller and Dave Sussman, who all looked absolutely worn out by Sunday evening – it wouldn’t have happened without you!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-7097102343786919271?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/lddUhty6wBo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/7097102343786919271/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=7097102343786919271" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7097102343786919271?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7097102343786919271?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/lddUhty6wBo/givecamp-uk-2011-retrospective.html" title="GiveCamp UK 2011 – A Retrospective" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/10/givecamp-uk-2011-retrospective.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEECQ304cCp7ImA9WhdVEko.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-7331496656979754333</id><published>2011-09-17T16:10:00.001+01:00</published><updated>2011-09-17T16:17:42.338+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-17T16:17:42.338+01:00</app:edited><title>Moleskine + Kindle = ... Moleskindle?</title><content type="html">&lt;p&gt;Faced with the harrowing prospect of trying to fit the entire &lt;a href="http://rcm-uk.amazon.co.uk/e/cm?lt1=_blank&amp;amp;bc1=000000&amp;amp;IS2=1&amp;amp;bg1=FFFFFF&amp;amp;fc1=000000&amp;amp;lc1=0000FF&amp;amp;t=dylanbeattieb-21&amp;amp;o=2&amp;amp;p=8&amp;amp;l=as4&amp;amp;m=amazon&amp;amp;f=ifr&amp;amp;ref=ss_til&amp;amp;asins=B0050AV5MW"&gt;Song of Ice and Fire&lt;/a&gt; into hand luggage on my next holiday, I bought a &lt;a href="http://www.amazon.co.uk/gp/product/B002Y27P46/ref=as_li_ss_tl"&gt;Kindle&lt;/a&gt;. It's quite magic. It won't switch off, it doesn't light up, it looks utterly fake - like some sort of plastic prop tablet device where they've used a printed cardboard screen... and it's absolutely lovely. My paperback books tend to end up rather battered from being slung around in bags all the time, and I wanted a case to keep the Kindle safe from knocks and scratches. Rather than spend money on one of the ridiculously overpriced cases you can get for it, I wanted to try something a bit different. You remember reading spy books as a kid where people would hide stuff inside hollowed-out books? &lt;/p&gt;  &lt;p&gt;I found an old Moleskine notebook that was just the right size for it, and started hacking away - a couple of happy hours playing with craft-knives and glue, and here it is: the Moleskindle&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://lh6.ggpht.com/-NFLyraErxTM/TnS6Bn_LG3I/AAAAAAAAAI0/U4jsSmqWbIg/s1600-h/IMG_8804%25255B8%25255D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="IMG_8804" border="0" alt="IMG_8804" src="http://lh3.ggpht.com/-7jdlNZyuwf0/TnS6CIxmoaI/AAAAAAAAAI4/RViSVeYzd-Y/IMG_8804_thumb%25255B5%25255D.jpg?imgmax=800" width="180" height="140" /&gt;&lt;/a&gt;&amp;#160;&lt;a href="http://lh6.ggpht.com/-qTz1rOd6WQU/TnS6DFPR1sI/AAAAAAAAAI8/rPq-eMm18rE/s1600-h/IMG_8810%25255B5%25255D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="IMG_8810" border="0" alt="IMG_8810" src="http://lh3.ggpht.com/-fgZnccBBEB8/TnS6DimQUdI/AAAAAAAAAJA/l7jDQLbYxS4/IMG_8810_thumb%25255B2%25255D.jpg?imgmax=800" width="180" height="140" /&gt;&lt;/a&gt;&amp;#160; &lt;br /&gt;&lt;a href="http://lh6.ggpht.com/-Ih18VYmloZs/TnS6EOBpI-I/AAAAAAAAAJE/3VmHqDlH1u8/s1600-h/IMG_8815%25255B5%25255D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="IMG_8815" border="0" alt="IMG_8815" src="http://lh6.ggpht.com/-Bl57D-uqjlE/TnS6EZj8ZmI/AAAAAAAAAJI/8ndfiEFYgrc/IMG_8815_thumb%25255B2%25255D.jpg?imgmax=800" width="180" height="140" /&gt;&lt;/a&gt;&amp;#160;&lt;a href="http://lh6.ggpht.com/-BnIeCMPQYDA/TnS6FFWRmHI/AAAAAAAAAJM/v3qkcZdA-SE/s1600-h/IMG_8814%25255B5%25255D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="IMG_8814" border="0" alt="IMG_8814" src="http://lh3.ggpht.com/-aEkXjPrYb-I/TnS6FXsZzLI/AAAAAAAAAJQ/EFilRV4nOLA/IMG_8814_thumb%25255B2%25255D.jpg?imgmax=800" width="180" height="140" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It's a bit fiddly - and messy - getting the cutouts just the right shape; I found wood glue worked just fine - and once it's dried, the compacted glued paper is quite easy to carve &amp;amp; trim using a sharp craft knife. I cut a notch in the right-hand side so I can reach the page-turn buttons whilst it's in the case, but you need to pop it out to reach the power button or recharge it. Still, I think it looks pretty cool, it'll stop the Kindle getting knocked and scratched, and you can fool people on the Tube into thinking you're reading something incredibly intellectual that's been hand-written in a Moleskine notebook when you're secretly reading &lt;a href="http://www.amazon.co.uk/This-Gonna-Hurt-Nikki-Sixx/dp/0062061879/ref=pd_sim_b4"&gt;rock star autobiographies&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-7331496656979754333?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/_Atq2YpIGEo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/7331496656979754333/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=7331496656979754333" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7331496656979754333?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7331496656979754333?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/_Atq2YpIGEo/moleskine-kindle-moleskindle.html" title="Moleskine + Kindle = ... Moleskindle?" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-7jdlNZyuwf0/TnS6CIxmoaI/AAAAAAAAAI4/RViSVeYzd-Y/s72-c/IMG_8804_thumb%25255B5%25255D.jpg?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/09/moleskine-kindle-moleskindle.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEENR3s7eSp7ImA9WhdWF0o.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-8803160301451491131</id><published>2011-09-11T22:31:00.001+01:00</published><updated>2011-09-11T22:31:36.501+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-11T22:31:36.501+01:00</app:edited><title>Software Development - HORSE-style</title><content type="html">&lt;p&gt;There's as many ways to lose at poker as there's ways to fail at delivering software, but one variation I have yet to experience is a game called &lt;a href="http://www.horsepoker.net/"&gt;HORSE&lt;/a&gt;. In HORSE, each hand follows a different set of rules - you'll play a hand of Hold'Em, a hand of Omaha, a hand of Razz, a hand of Stud, and a hand of Stud Hi-Lo; then you go back to the beginning and do it all over again, until my brother has all my chips.&lt;/p&gt;  &lt;p&gt;Inspired by this, I've devised the following brilliant software methodology for all those teams who can't quite settle on a system that works for them. It's called WALKS, and you work in two-week sprints, using a different methodology for each sprint to ensure you get the maximum efficiency from all these wonderful processes and systems:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Weeks 1-2: Waterfall       &lt;br /&gt;&lt;/strong&gt;You spend the first two weeks making bold, ambitious, big-design-up-front plans, and not actually writing any code or shipping any features.&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Weeks 3-4: Agile       &lt;br /&gt;&lt;/strong&gt;You spend the next two weeks trying desperately to get *something* built and releasable.&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Weeks 5-6: Lean       &lt;br /&gt;&lt;/strong&gt;Realizing that your &amp;quot;big design&amp;quot; is probably killing your attempts to be agile, you start hacking out unnecessary features and trying to pare the design back to something you might actually be able to build.&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Weeks 7-8: Kanban       &lt;br /&gt;&lt;/strong&gt;You still don't know what you're doing, so you decide to write everything on Post-It notes and stick them to a board, figuring that if you start pulling jobs off the queue, you might at least get *something* done.&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Weeks 9-10: Scrum        &lt;br /&gt;&lt;/strong&gt;You have two weeks of daily stand-up meetings, in a desperate attempt to try and get a handle on things. Finally, you sit down on Friday afternoon, have a two-hour timeboxed retrospective, and decide that what you &lt;em&gt;really &lt;/em&gt;need is a full set of requirements and a definitive spec.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Then you take a weekend off, come in on Monday, and start at the top again.&lt;/p&gt;  &lt;p&gt;If that sounds familiar, it's OK - you're not hopelessly lost, confused or unproductive; you're just taking a structured approach to being multi-disciplinary...&lt;/p&gt;  &lt;p&gt;&lt;font size="1"&gt;(This is a joke post. Please don't use WALKS to build software. Ever. The world has enough problems as it is...)&lt;/font&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-8803160301451491131?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/rOs14mb_4Y8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/8803160301451491131/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=8803160301451491131" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/8803160301451491131?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/8803160301451491131?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/rOs14mb_4Y8/software-development-horse-style.html" title="Software Development - HORSE-style" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/09/software-development-horse-style.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04BRnw6fyp7ImA9WhdREUQ.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-7348699307609583275</id><published>2011-08-01T12:59:00.001+01:00</published><updated>2011-08-01T12:59:17.217+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-01T12:59:17.217+01:00</app:edited><title>SkillsMatter Progressive.NET Tutorials 2011</title><content type="html">&lt;p&gt;Some of you may have heard about - or attended - &lt;a href="http://skillsmatter.com/event/open-source-dot-net/progressive-dot-net-tutorials-2011/wd-2388"&gt;SkillsMatter's Progressive.NET Tutorials&lt;/a&gt; over the last couple of years. This is a three-day program of in-depth workshops covering the latest languages, frameworks and techniques in .NET development. The great thing about the workshop format is that it provides enough time to actually get some hands-on experience; instead of the rapid-fire 45-minute lectures you'll find at most conferences, you can actually try things out, ask questions, work through examples, and really get to grips with the techniques or frameworks you're exploring.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://skillsmatter.com/event/open-source-dot-net/progressive-dot-net-tutorials-2011/wd-2388"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://skillsmatter.com/nl/prognet/prognet11_banner.gif" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This year, &lt;a href="http://codebetter.com/iancooper/"&gt;Ian Cooper&lt;/a&gt; - whom you may know from the &lt;a href="http://www.dnug.org.uk/"&gt;London .NET User Group&lt;/a&gt; - has put together a great programme of speakers and topics, and I'm really excited to say that, for the first time, I'll be there as a speaker instead of an attendee. &lt;/p&gt;  &lt;p&gt;My workshop is called &amp;quot;&lt;a href="http://skillsmatter.com/podcast/open-source-dot-net/front-end-tips-for-back-end-devs"&gt;Front-End Tips for Back-End Devs&lt;/a&gt;&amp;quot;. I'll be looking at how many of the techniques we take for granted in back-end development - including DRY, abstractions, packaging and dependency management -&amp;#160; can be applied to your page layouts, stylesheets and scripts. We'll cover semantic markup, we'll take a whirlwind tour of all the wonderful new tags introduced by HTML5, we'll look at CSS sprites and media queries, and we'll see how you can keep your web UI as clean, elegant and maintainable as the rest of your codebase.&lt;/p&gt;  &lt;p&gt;There's also &lt;a href="http://skillsmatter.com/expert-profile/ajax-ria/damjan-vujnovic"&gt;Damjan Vujnovic&lt;/a&gt; talking about TDD in JavaScript; I went along to one of Damjan's talks earlier this year and was really impressed, so I'm looking forward to the opportunity to go over his ideas in a little more depth. &lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;Jon Skeet&lt;/a&gt; will be talking about &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2011/07/28/speaking-engagement-progressive-net-london-september-7th.aspx"&gt;async/await programming on C# 5&lt;/a&gt; (no word yet on whether Tony the Pony will be there). There's workshops on continuous deployment, on web development in F# using the WebSharper framework, on packaging and dependency management, on REST, on Nancy, on SimpleData - in fact, if you've heard the .NET community buzzing about anything in the last year or so, chances are there's a workshop here that will show you what they're all so excited about. &lt;/p&gt;  &lt;p&gt;It's at the &lt;a href="http://skillsmatter.com/location-details/open-source-dot-net/849/96"&gt;SkillsMatter eXchange&lt;/a&gt; in London, from 5-7th September 2011. The cost is £425 (yes, it's not free, but you do get three days of top-notch content without giving up your evenings or weekends) - and &lt;strong&gt;you can use the promo code PROGNET50 to get £50 off.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://skillsmatter.com/event/open-source-dot-net/progressive-dot-net-tutorials-2011"&gt;Sign up online here&lt;/a&gt;. To keep up with event news, follow the hashtag &lt;a href="http://twitter.com/#!/search/%23prognet"&gt;#prognet&lt;/a&gt; on Twitter, and it'd be great to see you there.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-7348699307609583275?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/vOVUNCch_-M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/7348699307609583275/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=7348699307609583275" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7348699307609583275?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7348699307609583275?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/vOVUNCch_-M/skillsmatter-progressivenet-tutorials.html" title="SkillsMatter Progressive.NET Tutorials 2011" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/08/skillsmatter-progressivenet-tutorials.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUMRnc6eCp7ImA9WhZaE0o.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-7093045819229526256</id><published>2011-06-29T21:10:00.001+01:00</published><updated>2011-06-29T21:11:27.910+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-29T21:11:27.910+01:00</app:edited><title>Just Do It: Command-Query Segregation, Nike-Style</title><content type="html">&lt;p&gt;OK, CQRS is a hugely mis-applied and mis-understood architectural style. The insight I'm sharing here is based on my attending Udi Dahan's Advanced Distributed Systems Architecture course, then applying what I'd learned to a project we were building for 3-4 months, then having one of my colleagues go on the same course, and then have him come back and point out everything we'd done wrong. Let's assume you are already using CQRS. Maybe you're using it appropriately; maybe it's over-engineering; maybe it's completely misapplied. Doesn't matter, for what I have to say here; there are smarter folks than I who can tell you whether you should be doing it in the first place. No, I'm here to share a particular insight about CQRS with you.&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Your commands should be like a psychotic drill sergeant screaming orders.&lt;/strong&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://lh5.ggpht.com/-Tc6aCXoOOIc/TguG6I0JozI/AAAAAAAAAGg/U6XZf5RdPYE/s1600-h/image%25255B4%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-9aO3mKNTyQc/TguG7qxOalI/AAAAAAAAAGk/EbIYzjQsOwM/image_thumb%25255B2%25255D.png?imgmax=800" width="644" height="364" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;When you issue a command, &lt;strong&gt;your work is done. &lt;/strong&gt;End of story. Maybe it happens immediately. Maybe there's a delay, and someone has to wait a few seconds. Maybe it doesn't go according to plan, and somebody else notices afterwards, and they call someone else, and it gets fixed up. Maybe it fails spectacularly. You don't care. (Hell, you're probably dead by now. Nobody would ever have won any wars if everyone threw an exception when they found the sarge face-down in a fox-hole with a bullet-hole in his head.)&lt;/p&gt;  &lt;p&gt;You're the sarge. You are IN COMMAND. You order someone to destroy the ammo dump in North Camp, then you get on with your life. Tomorrow morning, you'll get a fresh intel report. Maybe it'll say that ammo dump in North Camp has been destroyed - maybe it won't. You'll review the fresh intelligence, decide what to next, issue a fresh batch of orders - and &lt;strong&gt;get on with your life. &lt;/strong&gt;That's CQRS. Your data is stale, your word is LAW, and you have better things to do than hang around wondering if you maybe did the wrong thing. If you give a command, and it doesn't get obeyed, there's exactly two potential outcomes:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Nobody notices&lt;/li&gt;    &lt;li&gt;Somebody notices&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;Nobody notices? &lt;/strong&gt;Cool. No problem. &lt;strong&gt;Somebody notices? &lt;/strong&gt;Well - that's where you hope it's one of your guys (i.e. alerts, logging, infrastructure, monitoring) instead of one of THEIR guys (i.e&amp;#160; customers/clients) That's how you do CQRS. Get your intelligence - your queries. The freshest data you can get, but don't bust a gut if it's a little out of date. Give your orders. Trust your intelligence. Get on with your life. Rinse. Repeat.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-7093045819229526256?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/uCwULiAp5ys" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/7093045819229526256/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=7093045819229526256" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7093045819229526256?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7093045819229526256?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/uCwULiAp5ys/just-do-it-command-query-segregation.html" title="Just Do It: Command-Query Segregation, Nike-Style" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-9aO3mKNTyQc/TguG7qxOalI/AAAAAAAAAGk/EbIYzjQsOwM/s72-c/image_thumb%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/06/just-do-it-command-query-segregation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IDR3o7fSp7ImA9WhZUGE0.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-5684595785671163246</id><published>2011-06-11T15:12:00.001+01:00</published><updated>2011-06-11T15:12:56.405+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-11T15:12:56.405+01:00</app:edited><title>How to install "Active Directory Users and Computers" on your Windows 7 Workstation</title><content type="html">&lt;p&gt;This one stumped me until I hit upon the magical combination that makes it work.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Install Windows 7 Service Pack 1.&lt;/li&gt;    &lt;li&gt;Download the &lt;a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=7887"&gt;Remote Server Administration Tools for Windows® 7 with SP1&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Install them.&lt;/li&gt;    &lt;li&gt;Reboot&lt;/li&gt;    &lt;li&gt;Go into Start -&amp;gt; Control Panel -&amp;gt; Programs and Features, and go to &amp;quot;Turn Windows features on or off&amp;quot; - because the installer will download and install the admin tools, but won't actually switch them on. Helpful.&lt;/li&gt; &lt;/ol&gt; &lt;a href="http://lh5.ggpht.com/-fOHA9UiZnGI/TfN35TdM4-I/AAAAAAAAAGY/_WMm5eSE-Yc/s1600-h/image%25255B4%25255D.png"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" title="image" alt="image" src="http://lh6.ggpht.com/-jLGdJvPd3HM/TfN35-OveaI/AAAAAAAAAGc/b3SDApHZXe4/image_thumb%25255B2%25255D.png?imgmax=800" width="811" height="362" /&gt;&lt;/a&gt;  &lt;p&gt;What makes it fun is that it just fails silently until you get it right. No error messages, no warnings... installer didn't even tell me I was missing SP1 - which I thought I already had.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-5684595785671163246?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/JKyl9nIqIGA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/5684595785671163246/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=5684595785671163246" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/5684595785671163246?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/5684595785671163246?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/JKyl9nIqIGA/how-to-install-directory-users-and.html" title="How to install &amp;quot;Active Directory Users and Computers&amp;quot; on your Windows 7 Workstation" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-jLGdJvPd3HM/TfN35-OveaI/AAAAAAAAAGc/b3SDApHZXe4/s72-c/image_thumb%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/06/how-to-install-directory-users-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkABSX8_eyp7ImA9WhZUFUo.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-5511041466646845480</id><published>2011-06-09T00:12:00.001+01:00</published><updated>2011-06-09T00:12:38.143+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-09T00:12:38.143+01:00</app:edited><title>Why Cloning Classic Games in Javascript Makes for a Great Hack Day</title><content type="html">&lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="When I needed a picture to go with &amp;quot;friction&amp;quot;, nothing else even came close... (Far Side © Gary Larson)" border="0" alt="Gary Larson / Far Side" align="right" src="http://www.johnstons.org/roy/comics/farside/fs24.gif" /&gt;Hack days should be about code. Anything that stops you writing code (or talking about / editing / refactoring code) is friction.&lt;/p&gt;  &lt;p&gt;There's two things in any software project that tend to cause huge amounts of friction - certainly during the early stages. One is tooling. Installing compilers takes time. Installing libraries takes time. Configuration takes time. I remember a day at Snowcode last year when we spent literally five hours installing Ruby, various build tools, make files, modules, browser automation components, plug-ins... I don't think I wrote a single line of code that day. It was interesting, and educational, but a hack day should be about &lt;strong&gt;building&lt;/strong&gt; stuff.&lt;/p&gt;  &lt;p&gt;The other huge source of friction in software development? Debates. There's X ways of doing something, and you can't make any progress until you've chosen one. Should we allow HTML in the comments? How big do we make the gallery thumbnails? &lt;a href="http://en.wikipedia.org/wiki/Parkinson's_Law_of_Triviality"&gt;What colour should we paint the bike-shed&lt;/a&gt;? On a &amp;quot;real&amp;quot; project, these decisions are made by the product owner - but for something like a hack-day, if you one person in charge of all the design, decision-making and prioritisation, they'll rapidly become a rather frustrated bottleneck.&lt;/p&gt;  &lt;p&gt;So - pick a problem that's clearly-defined and well-understood, and solve it using a language that everyone's already got, that doesn't need a compiler, linker or build environment, and that everyone can run just by opening a web browser.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In other words - clone a classic game in JavaScript. &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Choose something everyone's played. Bomberman. Tetris. Lemmings. Asteroids. Pac-man. Have a copy of the game on hand - on a laptop, or an emulator, or bring a console, or whatever - so if anyone asks questions, you can just refer to your definitive reference implementation and get back to work. That'll eliminate debate without handing anyone the poisoned chalice of product ownership on a volunteer-based project.&lt;/p&gt;  &lt;p&gt;And embrace the awesome lightweight expressiveness of JavaScript - the only language that you can write &lt;strong&gt;and run&lt;/strong&gt;, out of the box, on every single computer since Windows 98. There's no compiler. There's no IDE, no build chain, no runtime or virtual machine or standard libraries to install. People can use vi, Visual Studio, TextMate, Notepad - whatever they like. (Personally, &lt;a href="http://www.jetbrains.com/webstorm/"&gt;WebStorm&lt;/a&gt; is rocking my world right now - JavaScript intellisense and refactoring with built-in Git support... it's fantastic. Just remember that &lt;a href="http://youtrack.jetbrains.net/issue/WI-6561"&gt;Ctrl-Y doesn't redo by default&lt;/a&gt; and you'll love it.) &lt;/p&gt;  &lt;p&gt;OK, this weekend we were using NodeJS, so the build/run/test cycle involved restarting the node server (which is Ctrl-C, up, enter) - but the guys working on the renderer didn't even need a server. They built a client-side test harness (index.html), and their build and deployment cycle was Ctrl-S, Alt-Tab, F5. &lt;/p&gt;  &lt;p&gt;That's low friction. That's walking in off the street, opening up your laptop, pulling the code, and starting to build stuff straight away. And I like that.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-5511041466646845480?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/ET7F1IwBHEc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/5511041466646845480/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=5511041466646845480" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/5511041466646845480?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/5511041466646845480?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/ET7F1IwBHEc/why-cloning-classic-games-in-javascript.html" title="Why Cloning Classic Games in Javascript Makes for a Great Hack Day" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/06/why-cloning-classic-games-in-javascript.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcNRX8zeyp7ImA9WhZUEkU.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-1131711332786267890</id><published>2011-06-05T16:01:00.001+01:00</published><updated>2011-06-05T16:01:34.183+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-05T16:01:34.183+01:00</app:edited><title>Notes from the KaboomJS! LonDev Hack-Day</title><content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/dylanbeattie/5799010387/sizes/m/in/set-72157626763870203/"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 20px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" align="right" src="http://farm3.static.flickr.com/2740/5799010387_a491d3417e_d.jpg" width="240" height="181" /&gt;&lt;/a&gt;A couple of weeks back, I had this crazy idea to build Bomberman, in Javascript, in a day. I floated the idea on Twitter and got a pretty enthusiastic response, and so I set up the first LonDev hack day. 12 people, in a room, for one day, working together to build and ship a working game.&lt;/p&gt;  &lt;p&gt;Did we do it? You'll have to read all about it on the &lt;a href="http://www.londev.org/"&gt;new LonDev wiki&lt;/a&gt;, but personally, I'm really pleased at how it went, and really&amp;#160; excited at the idea of organising the next one.&lt;/p&gt;  &lt;p&gt;What's really encouraging is the mix of people and expertise who contributed. We had a couple of .NET coders, some Ruby/Rails guys, some JS web hackers who'd not done node/socket stuff before, and &lt;a href="http://twitter.com/#!/palfrey"&gt;@palfrey&lt;/a&gt; who, as far as I can tell, spends his days switching between Erlang and PHP to stop himself getting bored.&lt;/p&gt;  &lt;p&gt;A fun day. Some really solid code. Some really interesting lessons learned. And there's a couple of us hanging out in #kaboomjs on Freenode over the next few days to get it finished off and up and running.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-1131711332786267890?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/Y9arC6WsvR0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/1131711332786267890/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=1131711332786267890" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/1131711332786267890?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/1131711332786267890?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/Y9arC6WsvR0/notes-from-kaboomjs-londev-hack-day.html" title="Notes from the KaboomJS! LonDev Hack-Day" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/06/notes-from-kaboomjs-londev-hack-day.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIERXo6cSp7ImA9WhZQGE8.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-5248902532311589054</id><published>2011-04-26T13:55:00.001+01:00</published><updated>2011-04-26T13:55:04.419+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-26T13:55:04.419+01:00</app:edited><title>Want to work for Spotlight?</title><content type="html">&lt;p&gt;&lt;a href="http://www.spotlight.com/"&gt;Spotlight&lt;/a&gt; are hiring! We're looking for someone to join our software team full-time, in a senior development position. An experienced scrum master, who knows how to work with business and technical people to make things happen. Somebody who understands how to create great software. From database optimization to SOLID principles to TDD to user experience and accessibility, you understand what makes software great - great to use, great to maintain, great to extend.&lt;/p&gt;  &lt;p&gt;We’re at a turning point. Five years ago, we were an award-winning publishing company who maintained our own website. Five years from now, we’re going to be a software company who publish award-winning directories. It’s a great place to work, and it’s a really exciting time to be here. It’s full-time, permanent job, working at our office just off Leicester Square. We’re upstairs from the Prince Charles Cinema – London home of Sing-along-a-Sound-of-Music and The Room – and surrounded by excellent bars, restaurants and theatres.&lt;/p&gt;  &lt;p&gt;If you understand 90% of the postings on my blog, you’re probably in the right ball-park in terms of technology – but if you want buzzwords, it’s C#, .NET, agile, scrum, MVC, Castle Windsor, NHibernate, NServiceBus, jQuery, IIS, SQL Server, NUnit, SOA, TeamCity, FinalBuilder, msdeploy, and various other bits that are occasionally referred to as the “alt net stack”. &lt;/p&gt;  &lt;p&gt;Interested? Read the full job spec, and details of how to apply, at &lt;a href="http://www.spotlight.com/jobs/developer.html"&gt;www.spotlight.com/jobs/developer.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;NO AGENCIES. &lt;font size="1"&gt;Seriously. If we want to deal with agencies, we’ll call you. If you call me, I will put my phone handset in a drawer, close the drawer, and let you talk to my stationery while I wander off and make some coffee. If you’re lucky, it’ll only waste 90 seconds of your time. If you’re unlucky, your phone system still uses analogue-switched PSTN and you’ll find you can’t hang up. It’s hard to earn commission when you can’t use your phone, and you’d be surprised how long it takes to make a really good cup of coffee.&lt;/font&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-5248902532311589054?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/-LTbXn_zfys" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/5248902532311589054/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=5248902532311589054" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/5248902532311589054?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/5248902532311589054?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/-LTbXn_zfys/want-to-work-for-spotlight.html" title="Want to work for Spotlight?" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/04/want-to-work-for-spotlight.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EFRHc7eCp7ImA9WhZRFEs.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-3434613680972049063</id><published>2011-04-10T21:00:00.001+01:00</published><updated>2011-04-10T21:00:15.900+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-10T21:00:15.900+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="community" /><title>Slides and Notes from “So You Think You Know JavaScript”</title><content type="html">&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_de7B8BtZZIw/TaIMTb7NsoI/AAAAAAAAAGQ/HPZgew2umjQ/s1600-h/image%5B3%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://lh4.ggpht.com/_de7B8BtZZIw/TaIMT3nC8_I/AAAAAAAAAGU/ES69E2BEN3g/image_thumb%5B1%5D.png?imgmax=800" width="240" height="150" /&gt;&lt;/a&gt;The slides, notes and references from my JavaScript talk are now online, at     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;a href="http://www.dylanbeattie.net/javascript/"&gt;&lt;strong&gt;http://www.dylanbeattie.net/javascript/&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A huge thanks to everyone who came along, to &lt;a href="http://iancooper.brinkster.net/Frontpage.aspx"&gt;Ian Cooper and the LDNUG User Group&lt;/a&gt; for organising, and to &lt;a href="http://skillsmatter.com/"&gt;SkillsMatte&lt;/a&gt;r for the venue, the projector, the publicity, the video and the ginger tea. A &lt;a href="http://skillsmatter.com/podcast/ajax-ria/javascript-dotnet"&gt;full video of the talk&lt;/a&gt; is also available on the SkillsMatter website – and you’ll be pleased to hear that their awesome new video processing rig means you can now see my grinning face AND read the code samples on the slides.&lt;/p&gt;  &lt;p&gt;The NodeJS demo code is open source and is online at &lt;a href="https://github.com/dylanbeattie/BomberJS"&gt;https://github.com/dylanbeattie/BomberJS&lt;/a&gt; – fork it, pull it, do whatever you like with it. No warranties as to whether it’s any good or not… but it’s there and it works.&lt;/p&gt;  &lt;p&gt;A couple of people asked afterwards about running Node on Windows, as I was doing in the demos. I was using a compiled binary from &lt;a href="http://node-js.prcn.co.cc/"&gt;http://node-js.prcn.co.cc/&lt;/a&gt;, which worked absolutely fine for little demo apps with 5-6 concurrent client connections. I've no idea how it scales, but the general consensus seems to be that you should stick to Linux / MacOS for hosting any significant Node applications.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-3434613680972049063?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/OJM5MxYdQxg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/3434613680972049063/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=3434613680972049063" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/3434613680972049063?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/3434613680972049063?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/OJM5MxYdQxg/slides-and-notes-from-so-you-think-you.html" title="Slides and Notes from “So You Think You Know JavaScript”" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_de7B8BtZZIw/TaIMT3nC8_I/AAAAAAAAAGU/ES69E2BEN3g/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/04/slides-and-notes-from-so-you-think-you.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08DQnc6cSp7ImA9WhZRFEg.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-5432338305900039079</id><published>2011-04-10T17:05:00.001+01:00</published><updated>2011-04-10T17:11:13.919+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-10T17:11:13.919+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="agile" /><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Churn-down Charts</title><content type="html">&lt;p&gt;Our team have just finished a sprint on a project that’s using loads of new technology – MSMQ, NServiceBus, WCF – that we’ve not worked with before, and it’s played havoc somewhat with our estimates of how long everything was going to take. We hit our deadline, but only thanks to the product owner shifting a group of features into the next sprint, and at the retrospective everyone agreed that the process worked just fine but we didn’t have any really good way of visualising it. We have a &lt;a href="http://en.wikipedia.org/wiki/Burn_down_chart"&gt;burn-down chart&lt;/a&gt; – actually, we have two, ‘cos there’s one drawn on the whiteboard and there’s one in FogBugz as well – and what we’ve been doing is at the end of every day, we’ll just mark the number of hours left. On days when we discover more problems than we ship features, this looks like we’re moving backwards… which is true in terms of monitoring progress and planning, but isn’t great for morale, and it doesn’t really explain what’s going on. &lt;/p&gt;  &lt;p&gt;So, I’ve come up with this, as a way of tracking estimation accuracy and churn as well as straightforward progress. I’ve no idea if it’s original or not, I don’t know whether it has a name, but I’ve called mine a &lt;strong&gt;churn-down chart&lt;/strong&gt;. I’ve annotated this example to show you what happens over the course of the project – click for a bigger version.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_de7B8BtZZIw/TaHVYFA0yjI/AAAAAAAAAGI/5ug0p0-ac-4/s1600-h/churn_chart%5B5%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Churn-down Chart" border="0" alt="Churn-down Chart" src="http://lh3.ggpht.com/_de7B8BtZZIw/TaHVYjX7hKI/AAAAAAAAAGM/cMDpdepZc_I/churn_chart_thumb%5B3%5D.png?imgmax=800" width="481" height="480" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Basically – when the green line hits the red line, you’re done. The product owner controls the red line, by adding and removing features from the sprint. Yes, I know you’re not allowed to add stories to a sprint that’s in progress - I think the chart actually demonstrates why. The little blue tails were inspired by &lt;a href="http://www.nytimes.com/interactive/2010/02/02/us/politics/20100201-budget-porcupine-graphic.html"&gt;this fantastic visualisation of budget forecasts compared with reality&lt;/a&gt; (which I found via &lt;a href="http://chartporn.org/"&gt;Chart Porn&lt;/a&gt;), and they track how many hours of features we actually delivered that day, as opposed to how many hours we have left at the end of the day. This clearly shows the difference between days when we were productive but discovered lots of unplanned work, as opposed to days when we were just stuck.&lt;/p&gt;  &lt;p&gt;I like the way it empowers the product owner to actually work with the team to hit the deadline – you’re not working towards a fixed target, you’re both dealing with shifting requirements as you find bugs and have ideas, and you can see at a glance whether you’re on target or not, and if not, why not.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-5432338305900039079?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/lCwA4TR1Au0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/5432338305900039079/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=5432338305900039079" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/5432338305900039079?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/5432338305900039079?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/lCwA4TR1Au0/churn-down-charts.html" title="Churn-down Charts" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_de7B8BtZZIw/TaHVYjX7hKI/AAAAAAAAAGM/cMDpdepZc_I/s72-c/churn_chart_thumb%5B3%5D.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/04/churn-down-charts.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQHQnc5eip7ImA9WhZSGU0.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-8943274493220569141</id><published>2011-04-04T09:48:00.001+01:00</published><updated>2011-04-04T09:55:33.922+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-04T09:55:33.922+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="humour" /><title>Development Methodologies</title><content type="html">&lt;p&gt;By now, everyone’s seen test-driven development (TDD), behaviour-driven development (BDD) and domain-driven design (DDD) – but there’s some other, so far development paradigms that haven’t got nearly the attention that they deserve.&lt;/p&gt;  &lt;h3&gt;Attention Deficit Disorder Driven Design (ADDDD)&lt;/h3&gt;  &lt;p&gt;Most commonly seen in open-source projects. You begin by implementing a core feature. After a couple of days, when either it gets boring or you’ve coded yourself into a corner and can’t work out how to get out, you pick a new feature and start implementing that one instead. Advantages of this approach are that you can tick “in development” on the feature comparison charts when evaluating your solution against the alternatives. Disadvantages are that it leads to crappy software that doesn’t work.&lt;/p&gt;  &lt;h3&gt;Attention Deficit Hyperactive Disorder Driven Development (ADHDDD)&lt;/h3&gt;  &lt;p&gt;Just like ADDDD, but features are only ever added in brief caffeine-fuelled bursts of manic coding, usually around 4am, accompanied by dozens of tweets, blog posts and Facebook status updates.&lt;/p&gt;  &lt;h3&gt;Developer Developer Developer Driven Development (DDDDD)&lt;/h3&gt;  &lt;p&gt;Projects are started twice a year, normally the week immediately after the popular DDD community event at Microsoft headquarters, and generally involves building something really ground-breaking like a wiki or a blog engine, just to “get your head around” all the amazing new stuff you’ve seen at DDD. You’ll generally lose interest about two days after you put the code up on Github as a “pre-alpha technology demo”, and then six months later you’ll do the whole thing all over again.&lt;/p&gt;  &lt;h3&gt;Advanced Dungeons &amp;amp; Dragons Driven Development (AD&amp;amp;DDD)&lt;/h3&gt;  &lt;p&gt;Everyone sits around drinking Red Bull, eating Doritos, boasting about their accomplishments and pretending to be some sort of tenth-level software architect when deep down they’re still not quite sure what a pointer is. A “dungeon master” (also known as a “project manager”) occasionally rolls some dice or reads a Gartner report, and then tells them that their project has died. Then they do it all over again, once every couple of months, sometimes continuing well into middle age.&lt;/p&gt;  &lt;h3&gt;Acronym Driven Development (ADD)&lt;/h3&gt;  &lt;p&gt;The &lt;a href="http://www.horsepoker.net/"&gt;HORSE&lt;/a&gt; of development methodologies; you consistently blame the failure of your last project on the fact that you picked the wrong methodology, and resolve to try something different on your next project. The conventional approach is to go test-driven, then behaviour-driven, then domain-driven, then extreme, then back to domain-driven. It’s a very educational way of wasting your employer’s time and money, and there’s normally someone in a back room happily coding away who doesn’t have the faintest idea what the rest of you are doing, but is probably shipping enough features to keep your company afloat.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-8943274493220569141?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/HMq78utl5_0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/8943274493220569141/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=8943274493220569141" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/8943274493220569141?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/8943274493220569141?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/HMq78utl5_0/development-methodologies.html" title="Development Methodologies" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>5</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/04/development-methodologies.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ENQnc6cSp7ImA9WhZTGEw.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-803148564180919284</id><published>2011-03-22T17:41:00.001Z</published><updated>2011-03-22T17:41:33.919Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-22T17:41:33.919Z</app:edited><title>I’ll be talking about JavaScript at Skills Matter on April 5th</title><content type="html">&lt;p&gt;On April 5th I’ll be giving a talk on JavaScript at SkillsMatter here in London. It’s being organized by the London .NET User Group, but it’s not a .NET talk. Instead, it’ll cover a range of topics related to JavaScript’s history, the current state of the language, and the future of this widely-used and widely-misunderstood language.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://skillsmatter.com/podcast/home/javascript-dotnet/js-1532"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 20px 20px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" border="0" align="left" src="http://skillsmatter.com/custom/images/skills-matter_150x60_logo_2010.gif" /&gt;&lt;/a&gt;JavaScript is fifteen years old, and the principles that influenced JavaScript’s architecture go back to the very dawn of computer science. It’s a powerful, expressive, dynamic language, that’s now being used to deliver some of the biggest and &lt;a href="http://www.gmail.com"&gt;most popular&lt;/a&gt; software application &lt;a href="http://maps.google.co.uk/"&gt;in the world&lt;/a&gt; – and yet a whole generation of developers still thinks of JavaScript as being a scripting language that’s barely good enough to make pop-up windows appear on a web page.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_de7B8BtZZIw/TYjfS5PKgzI/AAAAAAAAAGA/4Q5p38X66Gg/s1600-h/image%5B4%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://lh5.ggpht.com/_de7B8BtZZIw/TYjfTfi75zI/AAAAAAAAAGE/j08d5t7jAVg/image_thumb%5B2%5D.png?imgmax=800" width="128" height="149" /&gt;&lt;/a&gt;There’s a lot of very cool stuff going on in the JavaScript world right now. With HTML5’s offline storage, you can use JavaScript to write client applications that you can install to your phone or your laptop and run them even when you’re offline. With &lt;a href="http://www.commonjs.org/"&gt;CommonJS&lt;/a&gt;, there’s finally a unified effort to create a standard runtime library for JavaScript so we can write JS programs that support file systems, networking, loadable modules and unit tests. With &lt;a href="http://nodejs.org/"&gt;NodeJS&lt;/a&gt;, there’s a fast, scalable&amp;#160; framework for writing HTTP servers as collections of discrete JavaScript components. With frameworks like &lt;a href="http://knockoutjs.com/"&gt;KnockoutJS&lt;/a&gt;, there’s declarative support for building rich web user interfaces in JavaScript - and it’s still pretty good at doing pop-up windows as well.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;So you think you know Javascript? &lt;/strong&gt;&lt;a href="http://skillsmatter.com/podcast/home/javascript-dotnet/js-1532"&gt;Sign up, come along&lt;/a&gt; and find out. I’ll bet you a pint there’s something in there you’ve never seen before.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-803148564180919284?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/tTbZxrooMmU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/803148564180919284/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=803148564180919284" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/803148564180919284?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/803148564180919284?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/tTbZxrooMmU/ill-be-talking-about-javascript-at.html" title="I’ll be talking about JavaScript at Skills Matter on April 5th" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_de7B8BtZZIw/TYjfTfi75zI/AAAAAAAAAGE/j08d5t7jAVg/s72-c/image_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/03/ill-be-talking-about-javascript-at.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEABRHw4eyp7ImA9Wx9bF0s.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-2751577998493534246</id><published>2011-02-26T23:23:00.000Z</published><updated>2011-02-26T23:25:55.233Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-26T23:25:55.233Z</app:edited><title>True Names, and Other Dangers: What Dr. Seuss Can Teach Us About SoA</title><content type="html">&lt;p align="center"&gt;&lt;em&gt;Did I ever tell you that Mrs. McCave, Had twenty-three sons, and she named them all Dave? &lt;/em&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;em&gt;Well, she did. And that wasn't a smart thing to do; You see, when she wants one, and calls out &amp;quot;Yoo-Hoo!      &lt;br /&gt;Come into the house, Dave!&amp;quot; she doesn't get one; All twenty-three Daves of hers come on the run!&lt;/em&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;em&gt;- from “&lt;a href="http://www.freondream.com/ice/daves.html"&gt;Too Many Daves&lt;/a&gt;” by Dr. Seuss&lt;/em&gt;&lt;/p&gt;  &lt;p align="justify"&gt;They say there’s only two hard problems in software – cache invalidation, naming things, and off-by-one errors. Cache invalidation’s hard because it’s difficult to clarify requirements. Off-by-one errors are hard because the joke wouldn’t work without them. But naming things? How hard can that be?&lt;/p&gt;  &lt;p align="justify"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 16px 16px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Sentences you never hear: " border="0" alt="The " align="right" src="http://www.cyberpunkreview.com/images/terminator06.jpg" width="240" height="136" movie.?="movie.?" Terminator="Terminator" The="The" from="from" listing="listing" phonebook="phonebook" Connor?="Connor?" Sarah="Sarah" Schwarzenegger??="Schwarzenegger??" *other*="*other*" the="The" him,="him," not="not" No,="No," Schwarzenegger.="Schwarzenegger." /&gt;If you’ve ever worked in IT support, you’ll have had calls saying “the system is down”. Sometimes, a more enlightened caller will helpfully tell you that it’s ‘the network’ or ‘the database’ that’s broken. I once started at a job where everybody referred to everything as “sequel.” There had been a big database migration a few years earlier, resulting in a new website and new desktop software, and the whole process had been referred to as “upgrading to SQL Server”. Everyone kept hearing the techies talk about “upgrading to sequel”, and so when they got something new on their desktops, they conclude “Ah – this must be that sequel thing that everyone’s been talking about!”. Two days later, they call you up and say there’s a problem with ‘sequel’ – and in this context, ‘sequel’ could refer to just about anything. The name was overloaded to the point of uselessness.&lt;/p&gt;  &lt;div align="justify"&gt;   &lt;div style="text-align: center; padding-bottom: 16px; padding-left: 16px; width: 200px; padding-right: 16px; float: left; margin-right: 8px; border-right: #000 1px solid; padding-top: 16px"&gt;&lt;strong&gt;“Ah yes - but it’s       &lt;br /&gt; &lt;font size="3"&gt;services&lt;/font&gt;         &lt;br /&gt;&lt;font size="4"&gt;all the way down&lt;/font&gt;!”&lt;/strong&gt;&lt;/div&gt; &lt;/div&gt;  &lt;p align="justify"&gt;What’s scary is that this happens all over the industry. People talk about “Software as a Service”, when what they’re actually dealing with is an XML web service, that’s connecting to a WCF service hosted in a Windows service to provide a business service. Like dear old Mrs. McCave, we’re finding out that names are great if they’re unique, but when different things start laying claim to the same names, you’re going to end up cross-eyed.&lt;/p&gt;  &lt;p align="justify"&gt;So, as my team start teasing apart our proverbial big ball of mud, I’m trying out a new naming policy for the new components and modules we’re building. Pick a word that sounds nice and doesn’t mean anything within our business. &lt;/p&gt;  &lt;p align="justify"&gt;The last three projects I worked on were called Rosemary, Tarragon and Kamogelo. No namespace conflicts, no semantic overloading and no clashing with reserved keywords. Rosemary’s almost like an employee – it has an event log, and a mailbox, and a sufficiently clear sense of identity that people seem to get it. When they say there’s a problem with Rosemary, they’re right; it doesn’t take 15 minutes to work out what they mean, and that’s a good thing. It also encourages clear separation of concerns, and facilitates good discussion thereof – lots of “does this feature belong in Rosemary or Tarragon?” instead of just adding another class to the legacy codebase. &lt;/p&gt;  &lt;p align="justify"&gt;So it’s goodbye, “customer e-mail service” and “accounts system” and “web shop”, and hello to Sundance, Monolith and Aquarius. And before too long, Moonface and PuttPutt and Shadrack, in recognition of dear old Mrs. McCave.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-2751577998493534246?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/S1LUOEytZ58" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/2751577998493534246/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=2751577998493534246" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/2751577998493534246?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/2751577998493534246?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/S1LUOEytZ58/true-names-and-other-dangers.html" title="True Names, and Other Dangers: What Dr. Seuss Can Teach Us About SoA" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/02/true-names-and-other-dangers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAHRnw6cCp7ImA9Wx9bFUg.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-1225535335593713285</id><published>2011-02-24T14:28:00.001Z</published><updated>2011-02-24T14:28:57.218Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-24T14:28:57.218Z</app:edited><title>Making HttpContext.Current Available Within a WCF Service</title><content type="html">&lt;p&gt;I needed to add a quick’n’dirty WCF service to an ASP.NET MVC web application, so I could call a handful of methods from a different application.&lt;/p&gt;  &lt;p&gt;The MVC app in question is using Windsor, NHibernate and the repository pattern, so we’ve got a fairly standard pattern where we spin up a ManagedWebSessionContext in the Application_BeginRequest handler (in global.asax.cs) and then flush and close the session in Application_EndRequest(). I used the Windsor WCF facility to inject a bunch of dependencies into a little WCF service, but I was finding that SessionFactory.GetCurrentSession() was always returning null – because when you’re using the ManagedWebSessionContext, your NHibernate session is bound to your HttpContext.Current, and by default you don’t have one of these inside a WCF service. &lt;/p&gt;  &lt;p&gt;However - if you can live with tight coupling between your WCF service and IIS hosting, there’s a couple of little config things you’ll need to do to get this working. What doesn’t help is that until you’ve got all this just right, you’ll get a really helpful “Failed to Execute URL” error from IIS that’ll tell you absolutely nothing about what’s wrong.&lt;/p&gt;  &lt;p&gt;First, make sure WCF HTTP activation is installed on your server – in Windows 2008, it’s under Server Manager –&amp;gt; Features:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://lh6.ggpht.com/_de7B8BtZZIw/TWZrJ6M0n4I/AAAAAAAAAFk/aSui0JLh5uI/s1600-h/image%5B3%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_de7B8BtZZIw/TWZrKMGJMkI/AAAAAAAAAFo/jQgFzTDa8Co/image_thumb%5B1%5D.png?imgmax=800" width="525" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Next, make sure you’ve registered the WCF service model with IIS, by running:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#a5a5a5"&gt;C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\&amp;gt;&lt;/font&gt; ServiceModelReg.exe –i&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Next, make sure your web service is running in ASP.NET compatibility mode. First, check you’ve got this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#a5a5a5"&gt;&amp;lt;system.serviceModel&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;serviceHostingEnvironment &lt;font color="#000000"&gt;&lt;strong&gt;aspNetCompatibilityEnabled=&amp;quot;true&amp;quot;&lt;/strong&gt;&lt;/font&gt; /&amp;gt;        &lt;br /&gt;&amp;lt;/system.serviceModel&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;in your web.config file, and then decorate your service implementation with the AspNetCompatibilityRequirements attribute:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;[AspNetCompatibilityRequirements(RequirementsMode= AspNetCompatibilityRequirementsMode.Required)]     &lt;br /&gt;&lt;font color="#a5a5a5"&gt;public class WcfMagicService : IMagicService {       &lt;br /&gt;&amp;#160;&amp;#160; . . .        &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The last thing I had to do was necessitated by WCF not supporting multiple host headers; I had to hard-wire the WCF endpoint to listen on a specific hostname. In this case, this involved tweaking the serviceHostingEnvironment section of web.config, which now looks like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#a5a5a5"&gt;&amp;lt;serviceHostingEnvironment aspNetCompatibilityEnabled=&amp;quot;true&amp;quot;&amp;gt;       &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;&amp;lt;baseAddressPrefixFilters&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;add prefix=http://services.mydomain.com” /&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/baseAddressPrefixFilters&amp;gt;        &lt;br /&gt;&lt;/strong&gt;&lt;font color="#a5a5a5"&gt;&amp;lt;/serviceHostingEnvironment&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And then adding another attribute to the service implementation class:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;[ServiceBehavior(AddressFilterMode=AddressFilterMode.Any)]       &lt;br /&gt;&lt;/strong&gt;&lt;font color="#a5a5a5"&gt;[AspNetCompatibilityRequirements(RequirementsMode= AspNetCompatibilityRequirementsMode.Required)]       &lt;br /&gt;public class WcfMagicService : IMagicService {        &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Once that’s done, you’ll have an instantiated HttpContext.Current inside your service methods, so your code – and useful things like NHibernate’s ManagedWebSessionContext – will behave just as they do in normal MVC controllers or WebForms code-behind.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-1225535335593713285?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/sD6Lp-ZXNvo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/1225535335593713285/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=1225535335593713285" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/1225535335593713285?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/1225535335593713285?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/sD6Lp-ZXNvo/making-httpcontextcurrent-available.html" title="Making HttpContext.Current Available Within a WCF Service" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_de7B8BtZZIw/TWZrKMGJMkI/AAAAAAAAAFo/jQgFzTDa8Co/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/02/making-httpcontextcurrent-available.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcFSHc4fSp7ImA9Wx9bE04.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-9118188328109451966</id><published>2011-02-21T23:46:00.001Z</published><updated>2011-02-21T23:46:59.935Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-21T23:46:59.935Z</app:edited><title>Check Out smtp4dev if You Build Mail-Enabled Software on Windows</title><content type="html">&lt;p&gt;&lt;a href="http://twitter.com/giantdave"&gt;One of my cow-orkers&lt;/a&gt; pointed me at a great little utility a while back called &lt;a href="http://smtp4dev.codeplex.com/"&gt;smtp4dev&lt;/a&gt;. It’s an SMTP server that listens on your local machine, and instead of relaying e-mail, it’ll capture them and store them in a queue so you can review and open them.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_de7B8BtZZIw/TWL5cJ2neAI/AAAAAAAAAFc/T3n46KwdwaE/s1600-h/image%5B3%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_de7B8BtZZIw/TWL5csD7XmI/AAAAAAAAAFg/Pjuf_5EW8nU/image_thumb%5B1%5D.png?imgmax=800" width="534" height="393" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It’s brilliant – simple and elegant and incredibly easy to use. Just configure your application (website, debugger, logging framework – whatever it is you’re building) to send mail on localhost:25, fire up smtp4dev, and watch the messages pile up. I’ve been building SMTP appenders for log4net this evening, and it’s been really, really useful.&lt;/p&gt;  &lt;p&gt;Binaries and source are at &lt;a href="http://smtp4dev.codeplex.com/"&gt;smtp4dev.codeplex.com&lt;/a&gt; – well worth a look if you ever write software that sends e-mail.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-9118188328109451966?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/BJmKWCddnh4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/9118188328109451966/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=9118188328109451966" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/9118188328109451966?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/9118188328109451966?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/BJmKWCddnh4/check-out-smtp4dev-if-you-build-mail.html" title="Check Out smtp4dev if You Build Mail-Enabled Software on Windows" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_de7B8BtZZIw/TWL5csD7XmI/AAAAAAAAAFg/Pjuf_5EW8nU/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/02/check-out-smtp4dev-if-you-build-mail.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UNQnk4cCp7ImA9Wx9UEU8.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-8173342425657493215</id><published>2011-02-07T23:28:00.001Z</published><updated>2011-02-07T23:28:13.738Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-07T23:28:13.738Z</app:edited><title>How to host Git in the same Apache server that comes with CollabNet Subversion</title><content type="html">&lt;p align="justify"&gt;&lt;a href="http://lh4.ggpht.com/_de7B8BtZZIw/TVCACwdo4_I/AAAAAAAAAFU/MybNY-C16R0/s1600-h/IMG_6726%5B7%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 20px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="This is the moon rising over the Costa Smeralda, Sardinia. It has nothing to do with revision control." border="0" alt="This is the moon rising over the Costa Smeralda, Sardinia. It has nothing to do with revision control." align="right" src="http://lh5.ggpht.com/_de7B8BtZZIw/TVCADJNcToI/AAAAAAAAAFY/3Gmsu7VpLFU/IMG_6726_thumb%5B4%5D.jpg?imgmax=800" width="320" height="240" /&gt;&lt;/a&gt;&lt;a href="http://www.collab.net/products/subversion/whatsnew.html"&gt;CollabNet Subversion Edge&lt;/a&gt; is a great Subversion distro that includes Apache 2.2 and the ViewVC web-based repo browser, and makes it really, really easy to get up and running with Subversion and WebDAV. I’m setting up a project server to host something we’re working on, and it’s been generally decided that whilst Subversion is all very well for keeping Word documents in, we’d quite like something a touch more… &lt;em&gt;distributed&lt;/em&gt; for the actual source code repo. And when &lt;a href="http://jagregory.com/"&gt;James Gregory&lt;/a&gt; mentioned on Twitter that git would mean “&lt;a href="http://twitter.com/#!/jagregory/status/34710468748779520"&gt;no more tree conflicts&lt;/a&gt; ”, I may have actually started salivating… ahem. &lt;/p&gt;  &lt;p align="justify"&gt;Anyway, yes. Apparently Git is quite good. &lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="http://www.jeremyskinner.co.uk/2010/07/31/hosting-a-git-server-under-apache-on-windows/"&gt;Jeremy Skinner has some fantastic notes&lt;/a&gt; on how to get git up and running with Apache 2.2. on a Windows server – I followed these pretty much to the letter to get my first incarnation up and running, but had to comment out a bunch of the Collabnet/Subversion settings in the Apache config files to get the Git server running properly. A bit of tinkering, though, and I’m pretty much there. What makes this interesting is that CollabNet includes a web-based admin console, which makes configuring the built-in modules very straightforward, but it does mean several of the config files have this rather ominous warning at the top:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="justify"&gt;&lt;strong&gt;#        &lt;br /&gt;# DO NOT EDIT THIS FILE IT WILL BE REGENERATED AUTOMATICALLY BY COLLABNET SUBVERSION&amp;#160; &lt;br /&gt;#&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="justify"&gt;so – any changes we make in there will be just peachy until someone touches the web interface, at which point BOOM! they’ll spontaneously stop working. So whatever we’re going to do, we need to do it without touching any of those files. I wasn’t sure at first whether this would be possible, but it seems to be up and running now and hanging together quite nicely. &lt;/p&gt;  &lt;p align="justify"&gt;Fire up the Apache httpd.conf file in &lt;a href="http://code.kliu.org/misc/notepad2/"&gt;your favourite editor&lt;/a&gt; – by default it’ll be in C:\Program Files\Subversion\data\conf\ – and add the following lines at the end:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="justify"&gt;&lt;em&gt;&lt;font color="#a5a5a5"&gt;# Configure Apache to listen for named virtual hosts on port 80         &lt;br /&gt;&lt;/font&gt;&lt;/em&gt;&lt;strong&gt;NameVirtualHost *:80&lt;/strong&gt;&lt;/p&gt;    &lt;p align="justify"&gt;&lt;em&gt;&lt;font color="#a5a5a5"&gt;# Include the configuration file for our git http hosting&lt;/font&gt;        &lt;br /&gt;&lt;/em&gt;&lt;strong&gt;Include &amp;quot;C:\Program Files\Subversion\data\conf\git_httpd.conf&amp;quot;&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="justify"&gt;Now create a new document called – yep - &lt;strong&gt;C:\Program Files\Subversion\data\conf\git_httpd.conf&lt;/strong&gt; – and make it look something like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="justify"&gt;&lt;font color="#a5a5a5"&gt;# HTTP settings for using Apache with MSysGit on Windows       &lt;br /&gt;# Based on Jeremy Skinner's notes at &lt;/font&gt;&lt;a href="http://www.jeremyskinner.co.uk/2010/07/31/hosting-a-git-server-under-apache-on-windows/"&gt;&lt;font color="#a5a5a5"&gt;http://www.jeremyskinner.co.uk/2010/07/31/hosting-a-git-server-under-apache-on-windows/&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p align="justify"&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;/p&gt;    &lt;p align="justify"&gt;&lt;font color="#a5a5a5"&gt;&amp;#160;&amp;#160;&amp;#160; # Set this to the root folder containing your Git repositories.       &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160; SetEnv GIT_PROJECT_ROOT D:/Git/      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&lt;font color="#a5a5a5"&gt;&amp;#160;&amp;#160;&amp;#160; # Set this to export all projects by default (by default,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; # git will only publish those repositories that contain a        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; # file named “git-daemon-export-ok”&lt;/font&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetEnv GIT_HTTP_EXPORT_ALL      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#a5a5a5"&gt;# Route specific URLS matching this regular expression to the git http server.       &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160; ScriptAliasMatch &amp;quot;(?x)^/git/(.*/(HEAD | info/refs | \      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; objects/(info/[^/]+ | [0-9a-f]{2}/[0-9a-f]{38} | pack/pack-[0-9a-f]{40}\.(pack|idx)) | \      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; git-(upload|receive)-pack))$&amp;quot; \       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;C:/Program Files (x86)/git/libexec/git-core/git-http-backend.exe/$1&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&lt;font color="#a5a5a5"&gt;&amp;#160;&amp;#160;&amp;#160; # The canonical DNS hostname that you want to use for your git server&lt;/font&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ServerName my_git_server      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&lt;font color="#a5a5a5"&gt;&amp;#160;&amp;#160;&amp;#160; # Any other DNS aliases that point to your git server&lt;/font&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ServerAlias my_git_server my_git_server.mydomain.com my_git_server.my_intranet.local      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&lt;font color="#a5a5a5"&gt;&amp;#160;&amp;#160;&amp;#160; # The root folder for non-GIT-hosted documents (e.g. phpgit or some other Web front end)&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DocumentRoot &amp;quot;D:\gitserver\htdocs\&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Location /&amp;gt;      &lt;br /&gt;&lt;font color="#a5a5a5"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; # This section is duplicated from the Collabnet SVN LDAP authentication        &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AuthType Basic      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AuthName &amp;quot;Spotlight GIT Repository&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AuthBasicProvider csvn-file-users ldap-users      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Require valid-user      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Location&amp;gt;      &lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="justify"&gt;Check your configuration by running httpd.exe from the command line, like so:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="justify"&gt;&lt;font color="#a5a5a5"&gt;C:\Program Files\Subversion\bin&amp;gt;&lt;/font&gt;&lt;strong&gt;httpd.exe -f &amp;quot;c:\program files\Subversion\data\conf\httpd.conf&amp;quot; –t       &lt;br /&gt;&lt;/strong&gt;Syntax OK&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="justify"&gt;and if all looks good, go into services.msc and restart the CollabNetSubversionServer service (which is actually Apache)&lt;/p&gt;  &lt;p align="justify"&gt;Finally, I followed Jeremy’s instructions to get GitPhp running, but then replaced it with a different project – also called GitPhp – from &lt;a href="http://www.xiphux.com/programming/gitphp/"&gt;http://www.xiphux.com/programming/gitphp/&lt;/a&gt;, which provides a full repository browser, revision history, etc.&lt;/p&gt;  &lt;p align="justify"&gt;All I had to do to get GitPHP running was to copy the gitphp.conf.php.example file to gitphp.conf.php, and then tweak the following settings:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="justify"&gt;&lt;font color="#a5a5a5"&gt;/* The root folder of my Git repositories */&lt;/font&gt;      &lt;br /&gt;$gitphp_conf['projectroot'] = 'D:\git';&lt;/p&gt;    &lt;p align="justify"&gt;&lt;font color="#a5a5a5"&gt;/* On 64-bit Windows, C:\Program Files (x86) ends up as C:\Progra~2\ so these need to be configured manually */&lt;/font&gt;      &lt;br /&gt;$gitphp_conf['gitbin']&amp;#160; = &amp;quot;C:\Progra~2\Git\bin\git.exe&amp;quot;;      &lt;br /&gt;$gitphp_conf['diffbin']&amp;#160; = &amp;quot;C:\Progra~2\Git\bin\diff.exe&amp;quot;;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="justify"&gt;Job done. I now have:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="justify"&gt;&lt;a href="http://my_svn_server/"&gt;http://my_svn_server/&lt;/a&gt; returning regular HTML pages hosted by Apache&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;&lt;a href="http://my_svn_server/svn/"&gt;http://my_svn_server/svn/&lt;/a&gt; giving me a WebDAV browser view on my raw Subversion repositories&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;&lt;a href="http://my_svn_server/viewvc/"&gt;http://my_svn_server/viewvc/&lt;/a&gt; giving me ViewCV web-browsable revision historys and diffs on my Subversion repos&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;&lt;a href="http://my_git_server/"&gt;http://my_git_server/&lt;/a&gt; giving me GitPHP browsing of my Git repositories&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;&lt;a href="http://my_git_server/git/"&gt;http://my_git_server/git/&lt;/a&gt;&amp;#160; exposing URLs for GIT cloning, fetching and pushing&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="justify"&gt;&lt;a href="http://my_iis_server/"&gt;http://my_iis_server/&lt;/a&gt; is still running IIS 7 with .NET 4 and MVC 3&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="justify"&gt;and that’s all on one box, with two IP addresses, with the svn and git servers sharing an instance of Apache on one address, the IIS server running on the other, and DNS records pointing svn and git at the first address and IIS at the second.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-8173342425657493215?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/Z8pW7TYEc54" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/8173342425657493215/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=8173342425657493215" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/8173342425657493215?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/8173342425657493215?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/Z8pW7TYEc54/how-to-host-git-in-same-apache-server.html" title="How to host Git in the same Apache server that comes with CollabNet Subversion" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_de7B8BtZZIw/TVCADJNcToI/AAAAAAAAAFY/3Gmsu7VpLFU/s72-c/IMG_6726_thumb%5B4%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/02/how-to-host-git-in-same-apache-server.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEQESH08cCp7ImA9Wx9UEU0.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-4678687183662531070</id><published>2011-02-07T19:18:00.001Z</published><updated>2011-02-07T19:18:29.378Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-07T19:18:29.378Z</app:edited><title>Running IIS and Apache on the same Windows 2008 R2 Server</title><content type="html">&lt;p&gt;I’m trying to get a Composite C1 site and the Apache WebDAV front-end to Subversion running on the same Windows 2008 R2 server, and doing so requires a bit of trickery with IP address bindings and such, and I thought I’d share it – partly ‘cos it’s useful, and partly because I’m bound to have to do this again in three months time and there’s no way I’ll remember how I did it. First off, make sure your box has (at least) two IP addresses – I’ve bound mine to 192.168.0.13 and 192.168.0.14&lt;/p&gt;  &lt;p&gt;To get IIS to listen on ONLY 192.168.0.13, you’ll need to run the netsh.exe utility. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;C:\Users\dylan.beattie&amp;gt;netsh&lt;/p&gt;    &lt;p&gt;netsh&amp;gt;http add iplisten ipaddress=192.168.0.13&lt;/p&gt;    &lt;p&gt;IP address successfully added&lt;/p&gt;    &lt;p&gt;netsh&amp;gt;http show iplisten&lt;/p&gt;    &lt;p&gt;IP addresses present in the IP listen list:     &lt;br /&gt;-------------------------------------------&lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; 192.168.0.13&lt;/p&gt;    &lt;p&gt;netsh&amp;gt;exit&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;(note that netsh.exe is a Windows 2008 utility – if you’re running Windows 2003 or earlier, look up the docs on using httpcfg.exe to achieve the same thing)&lt;/p&gt;  &lt;p&gt;If you now fire up a web browser and go to &lt;a href="http://192.168.0.13/"&gt;http://192.168.0.13/&lt;/a&gt;, you should get the default IIS7 “Welcome” screen, and &lt;a href="http://192.168.0.14/"&gt;http://192.168.0.14/&lt;/a&gt; shouldn’t return anything at all. Now to get Apache listening on 192.168.0.14. Find your httpd.conf file – if you’ve just installed CollabNet Subversion (like I have) it’ll be in the \data\conf folder of wherever you put your SVN install.&lt;/p&gt;  &lt;p&gt;You’ll need to find the Listen directive in httpd.conf, and modify it to say:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Listen 192.168.0.14:80&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That’s all. Next time – to get Git running on the same Apache installation… until then, happy hacking.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-4678687183662531070?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/kQ6SRW7jq-Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/4678687183662531070/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=4678687183662531070" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/4678687183662531070?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/4678687183662531070?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/kQ6SRW7jq-Y/running-iis-and-apache-on-same-windows.html" title="Running IIS and Apache on the same Windows 2008 R2 Server" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/02/running-iis-and-apache-on-same-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08CQH45cCp7ImA9Wx9WE00.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-796326214940347629</id><published>2011-01-17T23:11:00.001Z</published><updated>2011-01-17T23:11:01.028Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-17T23:11:01.028Z</app:edited><title>“Choose Life” For DBAs</title><content type="html">&lt;p&gt;I’m really really sorry. Someone tagged &lt;a href="http://search.twitter.com/search?q=%23sqlmoviequotes"&gt;#sqlmoviequotes&lt;/a&gt; on Twitter and I got carried away…&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;SELECT TOP(1) * FROM LIFE.&lt;/p&gt;    &lt;p&gt;SELECT TOP(1) * FROM JOB.&lt;/p&gt;    &lt;p&gt;SELECT TOP(1) * FROM CAREER.&lt;/p&gt;    &lt;p&gt;SELECT TOP(1) * FROM FAMILY.&lt;/p&gt;    &lt;p&gt;SELECT TOP(1) * FROM television ORDER BY SIZE DESC&lt;/p&gt;    &lt;p&gt;SELECT * FROM washing_machine CROSS JOIN car CROSS JOIN compact_disc_player CROSS JOIN electrical_tin_opener&lt;/p&gt;    &lt;p&gt;SELECT * FROM health, cholestorol, dental_insurance      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WHERE health.status = 'good' and cholestorol.level &amp;lt; 5      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;SELECT * FROM mortgage WHERE interest_rate = 'fixed'&lt;/p&gt;    &lt;p&gt;SELECT TOP(1) * FROM home WHERE TYPE = 'starter'&lt;/p&gt;    &lt;p&gt;SELECT * FROM person     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; INNER JOIN friendship ON person.id = friendship.person_id and friendship.friend_id = 'ME'&lt;/p&gt;    &lt;p&gt;SELECT * FROM leisurewear      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; INNER JOIN luggage ON leisurewear.color_scheme = luggage.color_scheme      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;SELECT TOP(3) * FROM lounge_furniture WHERE payment_plan = 'hire purchase'       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; AND range_id IN (SELECT range_id FROM fabric_option GROUP BY range_id HAVING COUNT(*) &amp;gt; @RANGE_SIZE)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;SELECT 'diy', CURRENT_USER FROM activity WHERE DATEPART(dw, activity_date) = 1 AND DATEPART(hh, activity_date) &amp;lt; 12&lt;/p&gt;    &lt;p&gt;DECLARE @your_mouth INT     &lt;br /&gt;DECLARE junk_food CURSOR FOR SELECT * FROM FOOD WHERE TYPE = 'junk'      &lt;br /&gt;WHILE @@CURRENT_SHOW IN (SELECT * FROM SHOW WHERE keyword IN ('mind_numbing', 'spirit-crushing')) BEGIN      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FETCH NEXT FROM junk_food INTO @your_mouth      &lt;br /&gt;END&lt;/p&gt;    &lt;p&gt;BEGIN&lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; sp_start_job 'brat'     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sp_start_job 'brat'      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sp_start_job 'brat'&lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; KILL @@SPID     &lt;br /&gt;END&lt;/p&gt;    &lt;p&gt;SELECT * FROM events WHERE EventDate &amp;gt; GETDATE()&lt;/p&gt;    &lt;p&gt;SELECT TOP(1) * FROM LIFE&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-796326214940347629?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/DR6o4550GWQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/796326214940347629/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=796326214940347629" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/796326214940347629?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/796326214940347629?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/DR6o4550GWQ/choose-life-for-dbas.html" title="“Choose Life” For DBAs" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/01/choose-life-for-dbas.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEESXkzeCp7ImA9Wx9XFkU.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-3393702070528790059</id><published>2011-01-10T19:26:00.001Z</published><updated>2011-01-10T19:26:48.780Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-10T19:26:48.780Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><category scheme="http://www.blogger.com/atom/ns#" term="subversion" /><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Mapping a Drive Letter to a Subversion Repository with CollabNet, WebDrive and WebDAV</title><content type="html">&lt;p&gt;This is quite neat. As part of a business-wide agile initiative, I’m looking into solutions for storing and collaborating on documents – something that gives *me* the history and auditing capabilities of something like Subversion, but gives the rest of the team something clean and easy that fits well with current working practises.&lt;/p&gt;  &lt;p&gt;So… mapped drive letters. Everyone knows about drive letters – “just stick it on the R: drive” is nice and easy, and as long as everyone’s R: drive points to the same place and the fileserver behind it’s getting backed up, you’re sorted. Unless you want to revert a document that’s been corrupted, or accidentally deleted, or you just want to get back an earlier revision because you realize you’ve done something dumb. Then you need to mess around with tapes and stuff, and that’s just no fun at all.&lt;/p&gt;  &lt;p&gt;Plus, of course, we have a wiki, which isn’t much fun to edit because the constant round-tripping from WYSIWYG-&amp;gt;markup-&amp;gt;HTML-&amp;gt;WYSIWYG tends to clobber newlines and formatting, but it *is* a great place to keep stuff because it doesn’t get lost.&lt;/p&gt;  &lt;p&gt;So, requirements for document storage:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;As easy to use as a drive letter. &lt;/li&gt;    &lt;li&gt;Security. Windows / LDAP authentication to control who can read and who can write. &lt;/li&gt;    &lt;li&gt;Revision history – just a record of who made changes, and when. &lt;/li&gt;    &lt;li&gt;Ability to revert changes to an earlier revision &lt;/li&gt;    &lt;li&gt;HTTP accessible so you can read stuff with just a web browser. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;There’s two things you can do with a list of requirements like that… speak to vendors, or hack something together yourself. You wanna speak to vendors, you go ahead; I shan’t stop you. Still here? Good. Let’s hack.&lt;/p&gt;  &lt;h4&gt;1. Install Subversion on the server. &lt;/h4&gt;  &lt;p&gt;For this, I’m using the &lt;a href="http://www.collab.net/products/subversion/whatsnew.html"&gt;CollabNet Subversion Edge&lt;/a&gt; stack – a single installer combining Subversion, Apache and the ViewVC web front-end. It’s very, very neat, and (having done this the hard way) &lt;em&gt;much&lt;/em&gt; easier than setting up mod_dav_svn yourself. Once it’s up, use the web interface (linked from the Start menu on your server) to set up a new repo – call it doc_repo – and then verify that if you browse to &lt;a href="http://myserver/viewvc/doc_repo/"&gt;http://myserver/viewvc/doc_repo/&lt;/a&gt; you get the ViewVC web front-end view of your new, empty repository.&lt;/p&gt;  &lt;p&gt;If you’re after Windows/LDAP authentication, that’s also configurable from the Subversion Edge web interface – and CollabNet has &lt;a href="http://blogs.open.collab.net/svn/2009/03/subversion-with-apache-and-ldap-updated.html"&gt;detailed notes on how this works&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_de7B8BtZZIw/TStdb3ntWII/AAAAAAAAAEo/JHxonYR9BpQ/s1600-h/image%5B4%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_de7B8BtZZIw/TStdcb8ZV8I/AAAAAAAAAEs/Qxj4cKZDaF4/image_thumb%5B2%5D.png?imgmax=800" width="573" height="741" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;2. Install &lt;strong&gt;&lt;a href="http://www.webdrive.com/products/webdrive/index.html"&gt;WebDrive&lt;/a&gt;&lt;/strong&gt; on your workstation.&lt;/h4&gt;  &lt;p&gt;This is a commercial package that’ll map a Windows drive letter to a WebDAV share. This is supposedly something that Windows is capable of doing natively, but I have never, ever got this to work, not even once. I would be glad to hear recommendations for free / open-source alternatives for this, since it’s currently the only bit of this set-up that costs money. There’s apparently also a &lt;a href="http://www.novell.com/coolsolutions/qna/999.html"&gt;netdrive.exe floating around&lt;/a&gt; but licensing for NetDrive seems to be a little confused.&lt;/p&gt;  &lt;h4&gt;3. Hack the Subversion config file. &lt;/h4&gt;  &lt;p&gt;On the server, open up &lt;font face="Consolas"&gt;C:\Program Files\Subversion\data\conf\svn_viewvc_httpd.conf&lt;/font&gt;. We’re not going to edit this file – you’ll need to find the bit that looks like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;Location /svn/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; DAV svn       &lt;br /&gt;&amp;#160;&amp;#160; SVNParentPath &amp;quot;C:\Program Files\Subversion\data\repositories&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160; SVNReposName &amp;quot;CollabNet Subversion Repository&amp;quot;       &lt;br /&gt;&amp;#160; AuthzSVNAccessFile &amp;quot;C:\Program Files\Subversion\data/conf/svn_access_file&amp;quot;       &lt;br /&gt;&amp;#160; SVNListParentPath On       &lt;br /&gt;&amp;#160; Allow from all       &lt;br /&gt;&amp;#160; AuthType Basic       &lt;br /&gt;&amp;#160; AuthName &amp;quot;CollabNet Subversion Repository&amp;quot;       &lt;br /&gt;&amp;#160; AuthBasicProvider csvn-file-users ldap-users       &lt;br /&gt;&amp;#160; Require valid-user       &lt;br /&gt;&amp;lt;/Location&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and copy it. Then open up &lt;font face="Consolas"&gt;C:\Program Files\Subversion\data\conf\httpd.conf&lt;/font&gt; – which is the regular Apache configuration file – and paste the copied section right at the end, and make the following changes:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#a5a5a5"&gt;# Change Location to be the URL path of your WebDAV repo – I’ve used &lt;em&gt;webdrive here         &lt;br /&gt;&lt;/em&gt;&lt;/font&gt;&amp;lt;Location&lt;font color="#4bacc6"&gt;&lt;strong&gt; /webdrive/&lt;/strong&gt;&lt;/font&gt;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DAV svn       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SVNParentPath &amp;quot;C:\Program Files\Subversion\data\repositories&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SVNReposName &amp;quot;Subversion WebDAV&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; AuthzSVNAccessFile &amp;quot;C:\Program Files\Subversion\data/conf/svn_access_file&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SVNListParentPath On       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Allow from all       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; AuthType Basic       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; AuthName &amp;quot;Document Repository&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; AuthBasicProvider csvn-file-users ldap-users       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Require valid-user       &lt;br /&gt;&lt;font color="#a5a5a5"&gt;# Add the two lines below &lt;/font&gt;      &lt;br /&gt;&lt;font color="#4bacc6"&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160; ModMimeUsePathInfo on          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SVNAutoversioning on           &lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;&amp;lt;/Location&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now restart the web server (using ApacheMonitor.exe from &lt;font face="Consolas"&gt;C:\Program Files\Subversion\bin\ &lt;/font&gt;on your server) and check that you can see &lt;a href="http://myserver/webdrive/"&gt;http://myserver/webdrive/&lt;/a&gt; in a normal Web browser – the screen should say “Collection of Repositories” with your doc_repo repository listed underneath.&lt;/p&gt;  &lt;h4&gt;4. Connect WebDrive to your new WebDEV-Enabled Repository&lt;/h4&gt;  &lt;p&gt;Nearly there. Finally, fire up WebDrive on your workstation and create a new connection. Enter the Site Address/URL as &lt;a href="http://myserver/webdrive/doc_repo/"&gt;http://myserver/webdrive/doc_repo/&lt;/a&gt; – note that you &lt;strong&gt;must put the repo name in the URL otherwise WebDrive will complain with an error something like:&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;code&gt;Unable to connect to server, error information below

Error: Socket receive failure (4507)
Operation: Connecting to server
Winsock Error: WSAECONNRESET (10054)&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;



&lt;p&gt;Correct settings will look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_de7B8BtZZIw/TStdcmWs2pI/AAAAAAAAAEw/iHMCiXNNDqE/s1600-h/image%5B10%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_de7B8BtZZIw/TStdc24_UMI/AAAAAAAAAE0/XgIpgoUC4Fg/image_thumb%5B6%5D.png?imgmax=800" width="644" height="442" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hit Connect, and Windows explorer will fire up a new N: drive window pointing at your repo.&lt;/p&gt;

&lt;h4&gt;5. Witness the Awesome Power of Autoversioning!&lt;/h4&gt;

&lt;p&gt;Create an empty folder, create a text file in it, then browse to &lt;a href="http://myserver/viewvc/doc_repo/"&gt;http://myserver/viewvc/doc_repo/&lt;/a&gt; and you should see your new folder, and file, along with the Subversion history recording who created the file and when:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_de7B8BtZZIw/TStdddljLwI/AAAAAAAAAE4/KwwcWACaGr0/s1600-h/image%5B14%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_de7B8BtZZIw/TStddx7f64I/AAAAAAAAAE8/KtAeE9nk3UA/image_thumb%5B8%5D.png?imgmax=800" width="869" height="553" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I like that a lot.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-3393702070528790059?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/OQHp4g5zJJ0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/3393702070528790059/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=3393702070528790059" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/3393702070528790059?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/3393702070528790059?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/OQHp4g5zJJ0/mapping-drive-letter-to-subversion.html" title="Mapping a Drive Letter to a Subversion Repository with CollabNet, WebDrive and WebDAV" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_de7B8BtZZIw/TStdcb8ZV8I/AAAAAAAAAEs/Qxj4cKZDaF4/s72-c/image_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2011/01/mapping-drive-letter-to-subversion.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08NRXw7eip7ImA9Wx9QGEg.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-2565149209941746079</id><published>2010-12-29T00:20:00.001Z</published><updated>2011-01-01T04:24:54.202Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-01T04:24:54.202Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="random" /><category scheme="http://www.blogger.com/atom/ns#" term="community" /><category scheme="http://www.blogger.com/atom/ns#" term="events" /><title>Christmas, Crisis and the Cloud</title><content type="html">&lt;p&gt;This Christmas, I volunteered at &lt;a href="http://www.crisis.org.uk/"&gt;Crisis&lt;/a&gt;, the UK charity that provides food, shelter and help for homeless people and rough sleepers over Christmas. It’s the first time I’d done anything like this, and – amongst stints of washing-up, manning doors, looking after showers, mopping and playing Articulate – I spent quite a lot of time helping with the suite of PCs that were provided for our guests to use. &lt;/p&gt;  &lt;p&gt;&lt;a title="Crisis IT Zone photo © Bob Johns" href="http://www.crisis.org.uk/gallery.php/24/crisis-at-christmas-2010#/gallery-image-large/24/_RJ_8987_1.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 20px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" border="0" align="right" src="http://www.crisis.org.uk/gallery-image-large/24/_RJ_8987_1.jpg" width="188" height="280" /&gt;&lt;/a&gt;It was a profound and enlightening experience. I use Gmail and Google Docs because they’re convenient – I regularly use 3-4 different PCs and online services are just a convenient way of keeping things accessible and in sync. It never really occurred to me that for someone who doesn’t have a computer of their own, or any regular access to one via a university or workplace, something as simple as a webmail account can be the difference between staying in touch and disappearing completely. People with no regular income, no phone and no fixed address were using Yahoo Mail to keep in touch with family and friends, apply for jobs and look for accommodation. It was quite amazing. I don’t know whether the folks at Yahoo, Gmail, Hotmail &lt;em&gt;et al&lt;/em&gt; realize just what a profound difference this makes – but if any of them are reading, well done. You rock, and I never realized quite how much until this week.&lt;/p&gt;  &lt;p&gt;Another interesting observation – Microsoft’s market saturation is so complete that even people who store their worldly possessions in a plastic shopping-bag insist on Microsoft Word. Their CVs are in Word format, they know the Word menus and commands – many of them are remarkably accomplished Word users. This is sad, because Word means Windows, and – even with the awesome job the people at the &lt;a href="http://www.theaimarfoundation.org/"&gt;Aimar Foundation&lt;/a&gt; had done setting up a locked-down Citrix system -&amp;#160; some machines became infected with a malware product called “Security Shield”. Security Shield masquerades as an anti-virus package,&amp;#160; makes a lot of bad noise about (non-existent) viruses and then asks the user for a credit card number to “activate the virus protection”. Well, Security Shield, this Christmas you &lt;strong&gt;actually asked the homeless for money&lt;/strong&gt;. Well done. You scared the hell out of frightened, vulnerable people who thought they’d broken the computer. You scared and upset the volunteers who were giving up their Christmas holiday to help those same people. I really hope you take all the money you’ve made from your little scam and spend it on something that’ll bring you joy in this life, because karma’s a bitch and your next life is going to suck.&lt;/p&gt;  &lt;p&gt;Anyway. Karmic retribution aside, it really got me thinking. For every iPad-toting hipster raving about how they keep all their stuff “in the cloud” because it’s the Next Big Thing, there’s a rough sleeper out there who genuinely doesn’t have anywhere else to keep it. There’s web mail, web docs, online tools for retouching photos, online games (spidersolitaire.com proved very popular with some of our guests), online video – you have no &lt;em&gt;idea&lt;/em&gt; how cool YouTube is to someone who doesn’t own a PC or a television - and I started wondering what else technology could offer.&lt;/p&gt;  &lt;p&gt;What about a complete online tool set and sandbox for people looking to learn about software development? Tutorials, exercises, a lab, workshop, CV and portfolio, accessible anytime, anywhere, for the cost of a virtual machine and a few gigs of disk space (i.e. practically nothing). A full development environment where they can learn to code, store projects, compile, test and deploy applications and websites – but accessible entirely within the sort of stripped-down web browser you'd find in most internet cafés. There’s no material reason why someone couldn’t learn to build software, establish an online presence, contribute to open-source projects, develop a reputation on Q&amp;amp;A sites like &lt;a href="http://www.stackoverflow.com/"&gt;StackOverflow&lt;/a&gt;, and generally become a &lt;em&gt;demonstrably employable&lt;/em&gt; developer, entirely without any investment in physical resources. The days of needing expensive computer time or equipment to become a coder are gone. The financial barrier to entry in our industry is effectively zero. We should be shouting this from the rooftops, doing everything possible to put information and resources in the hands of anyone who cares to take advantage of it, and celebrating this amazing consequence of the openness that’s sustained our industry for so long.&lt;/p&gt;  &lt;p&gt;Anyway. Crisis was awesome, you should &lt;em&gt;all&lt;/em&gt; do it next year, and here’s to a 2011 filled with compassion, kindness, enthusiasm and excitement. &lt;/p&gt;  &lt;p&gt;Happy New Year.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-2565149209941746079?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/DgshkMjuufg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/2565149209941746079/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=2565149209941746079" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/2565149209941746079?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/2565149209941746079?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/DgshkMjuufg/christmas-crisis-and-cloud.html" title="Christmas, Crisis and the Cloud" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2010/12/christmas-crisis-and-cloud.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQNQX07eip7ImA9Wx9TGUo.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-7282437427528894215</id><published>2010-11-28T19:25:00.001Z</published><updated>2010-11-28T19:26:30.302Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-28T19:26:30.302Z</app:edited><title>Git Logos and Icons</title><content type="html">&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_de7B8BtZZIw/TPKsn3uX1yI/AAAAAAAAAEQ/CEBmbI-7pxA/s1600-h/image%5B27%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 1px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://lh6.ggpht.com/_de7B8BtZZIw/TPKsoanKwPI/AAAAAAAAAEU/-kw3USmgb2c/image_thumb%5B13%5D.png?imgmax=800" width="260" height="152" /&gt;&lt;/a&gt;I’ve recently started working on a couple of projects that are hosted on Github, most notably the &lt;a href="https://github.com/Kurejito/Kurejito"&gt;Kurejito&lt;/a&gt; payment gateway project for which I’m a member of the core team on an OS project for the first time (yeah, scary…) &lt;/p&gt;  &lt;p&gt;Git is pretty cool. A bit of a learning curve but I suspect once I get the hang of frequent commits and local branching and work out how stop shooting myself in the foot it’s going to be quite hard going back to Subversion.&lt;/p&gt;  &lt;p&gt;Thing is, I really don’t like the Git icon and logo that are shipping with Mingw32 Git for Windows. I mean, I &lt;em&gt;really&lt;/em&gt; don’t like them. I don’t like them so much that every time I fire up git bash, I get completely distracted by how much I don’t like them and end up wanting to redesign them instead of doing whatever it was I was supposed to be doing… so I did.&lt;/p&gt;  &lt;p&gt;This started out as me just wanting a decent Windows icon for the link to Git Bash in my Start menu, I got a bit carried away, and ended up with this. And since Git appears to use a &lt;a href="https://git.wiki.kernel.org/index.php/GitRelatedLogos"&gt;collaboratively-edited Wiki page&lt;/a&gt; as the closest thing it has to brand and logo guidelines, if you want to use any of these logos or icons for your Git-related shortcuts, projects or pages, go ahead. I’m not going to stop you, and I suspect they won’t, either.&lt;/p&gt;  &lt;p align="center"&gt;&lt;/p&gt;  &lt;p align="left"&gt;If you’re interested, they’re released under a &lt;a href="http://creativecommons.org/licenses/by-sa/3.0/"&gt;Creative Commons Sharealike Attribution License&lt;/a&gt; – and there’s downloads (including Windows and Mac icon formats) and original artwork files at &lt;a href="http://www.dylanbeattie.net/git_logo/"&gt;http://www.dylanbeattie.net/git_logo/&lt;/a&gt; &lt;/p&gt;  &lt;p align="left"&gt;&lt;strong&gt;Direct download links:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div align="left"&gt;&lt;a href="http://lh3.ggpht.com/_de7B8BtZZIw/TPKspL3geOI/AAAAAAAAAEY/zNP0bZ8c92g/s1600-h/image%5B25%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://lh3.ggpht.com/_de7B8BtZZIw/TPKspmkSwxI/AAAAAAAAAEc/E5fl6pbMTpc/image_thumb%5B11%5D.png?imgmax=800" width="409" height="181" /&gt;&lt;/a&gt;Git Icon – Windows .ICO Format – &lt;a href="http://www.dylanbeattie.net/git_logo/git_icon.ico"&gt;git_icon.ico&lt;/a&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;Git icon in MacOS .icns format – &lt;a href="http://www.dylanbeattie.net/git_logo/git_icon.icns"&gt;git_icon.icns&lt;/a&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;Git icon original artwork – &lt;a href="http://www.dylanbeattie.net/git_logo/git_icon.ai"&gt;git_icon.ai&lt;/a&gt; or &lt;a href="http://www.dylanbeattie.net/git_logo/git_icon.png"&gt;git_icon.png&lt;/a&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;Git logo in PNG format – &lt;a href="http://www.dylanbeattie.net/git_logo/git_icon.png"&gt;git_logo.png&lt;/a&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;Git logo in Adobe Illustrator format – &lt;a href="http://www.dylanbeattie.net/git_logo/git_logo.ai"&gt;git_logo.ai&lt;/a&gt;&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div align="left"&gt;Git logo in SVG format – &lt;a href="http://www.dylanbeattie.net/git_logo/git_logo.svg"&gt;git_logo.svg&lt;/a&gt;&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p align="left"&gt;or grab the whole package as &lt;a href="http://www.dylanbeattie.net/git_logo/git_icon_and_logo.zip"&gt;git_icon_and_logo.zip&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-7282437427528894215?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/Gcz1OBtT-3E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/7282437427528894215/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=7282437427528894215" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7282437427528894215?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7282437427528894215?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/Gcz1OBtT-3E/git-logos-and-icons.html" title="Git Logos and Icons" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_de7B8BtZZIw/TPKsoanKwPI/AAAAAAAAAEU/-kw3USmgb2c/s72-c/image_thumb%5B13%5D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2010/11/git-logos-and-icons.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYMSXY4cCp7ImA9Wx9TF0o.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-6579781630100908216</id><published>2010-11-26T11:46:00.001Z</published><updated>2010-11-26T11:49:48.838Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-26T11:49:48.838Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Sending Templated E-mail using the Spark View Engine</title><content type="html">&lt;p&gt;&lt;a title="Spark photograph © SCholewiak via Flickr" href="http://www.flickr.com/photos/scholewiak/145096304/sizes/m/in/photostream/"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 20px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="" border="0" alt="Spark photo © SCholewiak via Flickr" align="right" src="http://farm1.static.flickr.com/47/145096304_0ff99eec39.jpg" width="320" height="241" /&gt;&lt;/a&gt;We have a couple of systems that send personalized e-mail notifications to our users, and for a while I’ve been looking for a nice way to use a proper MVC-style view engine to populate the templates for personalizing these e-mails. The problem is, most of the ASP.NET view engines are so tightly bound to System.Web and things like HttpContext.Current and the VirtualPathProvider that running them in a standalone console application is really quite unpleasant.&lt;/p&gt;  &lt;p&gt;Well, with a bit of hacking around and some help from &lt;a href="http://twitter.com/#!/RobertTheGrey"&gt;@RobertTheGrey&lt;/a&gt;, I’ve finally got the awesome &lt;a href="http://sparkviewengine.com/"&gt;Spark view engine&lt;/a&gt; running within a console app. No fake VirtualPathProviders, no mocking or spoofing HttpContext.Current – it just works.&lt;/p&gt;  &lt;p&gt;The secret is this little snippet of code here:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;var templateFolder = @&amp;quot;D:\Templates\&amp;quot;;        &lt;br /&gt;var viewFolderParameters = new Dictionary&amp;lt;string, string&amp;gt; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;quot;basePath&amp;quot;, templateFolder}         &lt;br /&gt;};         &lt;br /&gt;var settings = new SparkSettings();         &lt;br /&gt;settings.SetPageBaseType(typeof(TemplateBase));         &lt;br /&gt;settings.AddViewFolder(ViewFolderType.FileSystem, viewFolderParameters);         &lt;br /&gt;engine = new SparkViewEngine(settings);&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;which spins up a fresh SparkSettings configuration object, tells it to use your own TemplateBase class and the templates folder you’ve specified. The method that actually does the population looks like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;public string Populate(string templateFileName, object data) {&amp;#160; &lt;br /&gt;&amp;#160; var writer = new StringWriter();&amp;#160; &lt;br /&gt;&amp;#160; var descriptor = new SparkViewDescriptor();&amp;#160; &lt;br /&gt;&amp;#160; descriptor.AddTemplate(templateFileName);&amp;#160; &lt;br /&gt;&amp;#160; var view = (TemplateBase)engine.CreateInstance(descriptor);&amp;#160; &lt;br /&gt;&amp;#160; try {&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; view.ViewData = new ViewDataDictionary(data);&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; view.RenderView(writer);&amp;#160; &lt;br /&gt;&amp;#160; } finally {&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; engine.ReleaseInstance(view);&amp;#160; &lt;br /&gt;&amp;#160; }&amp;#160; &lt;br /&gt;&amp;#160; return (writer.ToString());&amp;#160; &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;so you end up with little snippets like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;foreach(var user in userRepository.RetrieveUsersWhoShouldGetWelcomeEmails()) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var htmlBody = templater.Populate(&amp;quot;welcome_html.spark”, user):        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var textBody = templater.Populate(“welcome_text.spark”, user):        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; mailServer.SendMail(&lt;/font&gt;&lt;a href="mailto:&amp;ldquo;me@mysite.com"&gt;&lt;font face="Consolas"&gt;“me@mysite.com&lt;/font&gt;&lt;/a&gt;&lt;font face="Consolas"&gt;”, user.Email, “Welcome!”, textBody, htmlBody);       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;There’s a &lt;a href="https://github.com/loudej/spark/tree/master/src/Samples/DirectUsage/SparkEmailMerge"&gt;full working example in the Spark repository on GitHub&lt;/a&gt; if you’re interested.&lt;/p&gt;  &lt;p&gt;&lt;font size="1"&gt;Spark photo © &lt;a href="http://www.flickr.com/photos/scholewiak/145096304/sizes/m/in/photostream/"&gt;SCholewiak via Flickr&lt;/a&gt; – used under Creative Commons attribution license.&lt;/font&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-6579781630100908216?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/x6zf1FePxOc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/6579781630100908216/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=6579781630100908216" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/6579781630100908216?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/6579781630100908216?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/x6zf1FePxOc/sending-templated-e-mail-using-spark.html" title="Sending Templated E-mail using the Spark View Engine" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm1.static.flickr.com/47/145096304_0ff99eec39_t.jpg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2010/11/sending-templated-e-mail-using-spark.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04NQngycSp7ImA9Wx5aEEQ.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-7610625444580426350</id><published>2010-11-03T19:02:00.002Z</published><updated>2010-11-07T01:06:33.699Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-07T01:06:33.699Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sagepay usability design" /><title>Should “Cancel” cancel the cancellation, or just cancel the cancellation cancellation?</title><content type="html">&lt;p&gt;This is from SagePay’s new MySagePay admin system, which has brought us all so much joy these past weeks and will go down in history as my second favourite piece of web design ever, after &lt;a href="http://www.kibo.com/webtv/webtv.html"&gt;Kibo’s Optimised for WebTV! page&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Today’s happy little discovery. You click to view a transaction. You think “Oops, wrong transaction.” Years of Windows experience means you instinctively hit &lt;strong&gt;Cancel &lt;/strong&gt;– the button marked Cancel, that’s at the bottom-right of the window, just like it is on every other dialog box you’ve seen in the last 25 years. But guess what? In this case, the &lt;strong&gt;Cancel&lt;/strong&gt; button actually &lt;em&gt;cancels the transaction&lt;strong&gt;, &lt;/strong&gt;&lt;/em&gt;rather than closing the window and backing out of the operation.&lt;/p&gt;  &lt;p&gt;Of course, it wouldn’t do anything that drastic without a confirmation dialog… guess what &lt;strong&gt;that&lt;/strong&gt; dialog looks like?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_de7B8BtZZIw/TNGxy31rbQI/AAAAAAAAADw/45KcT3c-l20/s1600-h/image%5B7%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_de7B8BtZZIw/TNGxzVxTJQI/AAAAAAAAAD0/Q5hbKVlp-NU/image_thumb%5B5%5D.png?imgmax=800" width="804" height="492" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;“Cancel” means exactly the same thing in practically every application, window manager and operating system that’s been released for the last 25 years. The idea that anyone might think that using it for a different purpose in a different context is… just unbelievable. &lt;/p&gt;  &lt;p&gt;Moral of the story: if your ubiquitous language contains a word or phrase that everyone &lt;em&gt;knows&lt;/em&gt; means something else – change the ubiquitous language. Think of a better word. Here’s some to get you started… Unauthenticate. Withdraw. Retract. Deauthenticate. Discard. Abandon. Reject. Decline. Even “Cancel Transaction” would have been better than this.&lt;/p&gt;  &lt;p&gt;So – to cancel a transaction, you hit Cancel, then Cancel again. To cancel the cancellation, you hit Cancel, but DON’T press Cancel, press X and then X.&lt;/p&gt;  &lt;p&gt;(and yeah, to cancel the &lt;em&gt;dialog&lt;/em&gt; as opposed to the transaction, you click the groovy little X in the top corner, because this is Web 2.0, dontcha know?)&lt;/p&gt;  &lt;p&gt;Obvious, really.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-7610625444580426350?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/_NT-5JDuHpI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/7610625444580426350/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=7610625444580426350" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7610625444580426350?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/7610625444580426350?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/_NT-5JDuHpI/should-cancel-cancel-cancellation-or.html" title="Should “Cancel” cancel the cancellation, or just cancel the cancellation cancellation?" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_de7B8BtZZIw/TNGxzVxTJQI/AAAAAAAAAD0/Q5hbKVlp-NU/s72-c/image_thumb%5B5%5D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2010/11/should-cancel-cancel-cancellation-or.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcARHo9eCp7ImA9Wx5aEEQ.&quot;"><id>tag:blogger.com,1999:blog-7295454224203070190.post-326293442142061444</id><published>2010-10-26T02:23:00.001+01:00</published><updated>2010-11-07T01:07:25.460Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-07T01:07:25.460Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sagepay agile tdd" /><title>“If It Ain’t Broke…” – Why Good Code Doesn’t Guarantee Happy Users</title><content type="html">&lt;p&gt;For years, my sites have processed online payments using a firm called Protx. Protx was acquired by Sage a few years back, rebranded as &lt;a href="http://www.sagepay.com/"&gt;SagePay&lt;/a&gt;, and since then they’ve been gradually making changes to their system. Nothing too drastic, and always with plenty of warning that changes were forthcoming. Their payment API is generally rock-solid, powerful, flexible, and has allowed us to cope with all sorts of complicated payment scenarios without too much fuss. So far, so good.&lt;/p&gt;  &lt;p&gt;About two months ago, SagePay announced that a preview of their new administration system was running on their test servers, and they invited everyone to go and have a look. Their old system was kinda clunky, but it worked, and our accounts team had been using it quite happily for years. So I went. I looked. The new system had lots of shiny Ajax – OK, fair enough, this is 2010 after all – and horizontal scrolling. No, really. Check this out:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_de7B8BtZZIw/TMWYRsMxWHI/AAAAAAAAADg/jCmZCnP_W0k/s1600-h/image%5B6%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_de7B8BtZZIw/TMWYR8F5AxI/AAAAAAAAADk/BmtEcSFPysw/image_thumb%5B4%5D.png?imgmax=800" width="335" height="258" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I have a 1600x1200 screen because information is nice  and I like being able to see lots of it at once. SagePay have decided, for some reason, that our payment transactions are best presented in a fixed-size 800x300px window. Fine, though – that’s what technical previews are for; lots of people reported this and were &lt;a href="https://support.sagepay.com/forum/Topic11656-26-2.aspx#bm11685"&gt;assured it would be sorted out&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Well, the new system launched over the weekend. The old one’s gone, they new one’s live, and things like the horizontal scrolling have &lt;em&gt;not&lt;/em&gt; been sorted out, and customers’ reactions to the new system is, well, a bit negative. A thread &lt;a href="https://support.sagepay.com/forum/Topic11656-26-2.aspx"&gt;on their support forums&lt;/a&gt; is full of gems like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“A complete crock. Should be rolled back immediately.” (&lt;a href="https://support.sagepay.com/forum/FindPost11697.aspx"&gt;here&lt;/a&gt;)&lt;/p&gt;    &lt;p&gt;“this is a complete and utter disaster. This system needs rolling back as soon as possible.” (&lt;a href="https://support.sagepay.com/forum/FindPost11699.aspx"&gt;here&lt;/a&gt;)&lt;/p&gt;    &lt;p&gt;“The system is rejecting the order because of the delivery address line 2 which contained 58-62 xxxxx Road. Your system is not allowing the - in the address (This address is the formatted address that is provided by Royal Mail). This needs to be fixed quickly.” (&lt;a href="https://support.sagepay.com/forum/FindPost11707.aspx"&gt;here&lt;/a&gt;)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;OK, fine. Big company rolls out shiny upgrade, upsets customers, breaks APIs, whatever. Big companies do this a lot. &lt;/p&gt;  &lt;p&gt;But - I was expecting something different here, because last week, Mat – SagePay’s “Chief Nerd” – published &lt;a href="http://sagepay.wordpress.com/2010/10/18/if-it-aint-broke/"&gt;this blog post&lt;/a&gt;, in which he talks quite rationally and eloquently about the forthcoming improvements. And it sounds like quite good stuff, too. Stuff like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“To accommodate this we’ve changed the way we develop software, not only at a language level, but also at the process level.  We’ve embraced Test Driven Development, Agile methodologies, Continuous Integration and parallel automated testing.”&lt;/p&gt;    &lt;p&gt;“By writing tests first and only then writing code that passes those tests, we know that our software does what it is supposed to.”&lt;/p&gt;    &lt;p&gt;“This demonstrable code quality gives our developers much more confidence in their code, frees them to refactor software that behaves sub-optimally, and ensures the test team’s time isn’t wasted on trivial bugs.”&lt;/p&gt;    &lt;p align="right"&gt; (quotes from &lt;a title="http://sagepay.wordpress.com/2010/10/18/if-it-aint-broke/" href="http://sagepay.wordpress.com/2010/10/18/if-it-aint-broke/"&gt;http://sagepay.wordpress.com/2010/10/18/if-it-aint-broke/&lt;/a&gt;)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;OK. Mat, I believe you. If your comments about improved capacity and security are correct, this actually represents a huge achievement for the SagePay technical team. But I have to wonder… if the chief nerd is doing everything right, why are the customers so upset?&lt;/p&gt;  &lt;div style="padding-bottom: 8px; line-height: 2em; padding-left: 8px; width: 240px; padding-right: 8px; float: left; font-size: large; margin-right: 8px; border-right: #999999 1px solid; padding-top: 8px"&gt;   &lt;p align="center"&gt;&lt;span &gt;&lt;span &gt;“&lt;/span&gt;&lt;strong&gt;&lt;span &gt;…if the&lt;/span&gt;          
CHIEF NERD          
&lt;span &gt;is doing&lt;/span&gt; &lt;span &gt;EVERYTHING&lt;/span&gt; RIGHT,          
&lt;span &gt;why are the           
&lt;/span&gt;&lt;span &gt;CUSTOMERS &lt;/span&gt;&lt;span &gt;so&lt;/span&gt; UPSET?&lt;/strong&gt;&lt;/span&gt;&lt;span &gt;”&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Well, this is what I think probably happened. First, they’ve been working on this since June 2009; the first real customer preview was in September 2010, and it’s now live, just over a month later. That’s not a series of incremental improvements, delivering discrete chunks of business value every few weeks or months. That’s the &lt;a href="http://www.joelonsoftware.com/articles/fog0000000069.html"&gt;big&lt;/a&gt; &lt;a href="http://chadfowler.com/2006/12/27/the-big-rewrite"&gt;rewrite&lt;/a&gt; wearing a not-very-convincing Agile disguise. &lt;/p&gt;  &lt;p&gt;Second, one of the core tenets of the Agile Manifesto is “&lt;strong&gt;customer collaboration&lt;/strong&gt; over contract negotiation” – and to get that right, you have to know who your customers really are, and &lt;em&gt;collaborate&lt;/em&gt; with them. This is tricky, because to the developers, the ‘customer’ is probably the product owner – but in reality, the customer should be the person who’s going to use the product. Now a firm like SagePay probably can’t call their customers in off the street to collaborate on a big project like this – but they &lt;em&gt;can&lt;/em&gt; talk to them.  &lt;/p&gt;  &lt;p&gt;I think it’s really easy – particularly in big companies – to get this wrong. I have made this mistake many times. You launch version 1.0, you spend a couple of years babysitting it and fielding the support calls, and you end up thinking you know exactly what all your customers want… except you don’t, because &lt;em&gt;happy users never call support&lt;/em&gt;. They just use the product and get on with their lives. You can find out what your users &lt;em&gt;don’t&lt;/em&gt; like from support calls and complaints, but to find out what they &lt;em&gt;do&lt;/em&gt; like, you need to get out there and talk to them, and it sounds like many of the features in the new SagePay system were based on feature requests and complaints from a vocal minority who weren’t really representative of the user base as a whole. It feels like you’re doing exactly the right thing, but you’re not actually &lt;em&gt;collaborating&lt;/em&gt; with your customer.&lt;/p&gt;  &lt;div style="padding-bottom: 8px; line-height: 2em; padding-left: 8px; width: 240px; padding-right: 8px; float: right; font-size: large; padding-top: 8px"&gt;   &lt;p align="center"&gt;&lt;span &gt;“&lt;strong&gt;REAL USERS &lt;/strong&gt;&lt;/span&gt; 
don't care about      
&lt;span &gt;&lt;strong&gt;TEST DATA&lt;/strong&gt;”&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Second – technical previews are all very well, but &lt;strong&gt;real users don’t care about test data&lt;/strong&gt;. When I tried the new MySagePay tech preview last month, it had about a dozen transactions in it, from 2006, when we were testing an upgrade to our own payment system. That’s not a realistic test of the system, because there’s no incentive to actually do anything with it. The only way to get &lt;strong&gt;real feedback &lt;/strong&gt;is to get &lt;strong&gt;real people &lt;/strong&gt;to use the software to do &lt;strong&gt;real work &lt;/strong&gt;– and &lt;strong&gt;you can’t do real work with test data&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;In a nutshell, I think they missed the distinction between &lt;strong&gt;have we built the right thing?&lt;/strong&gt; and &lt;strong&gt;have we built it right?&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;TDD, Continuous Integration, refactoring – these will all help you &lt;strong&gt;build it right, &lt;/strong&gt;but agile’s also about making sure you’re building the &lt;strong&gt;right thing, &lt;/strong&gt;and I think SagePay dropped the ball on this one.&lt;/p&gt;  &lt;p&gt;Mat even says (my emphasis)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“…any change introduces risk. … We might produce new software that performs identically to the old for a given payment protocol only to find that two thousand customers are &lt;strong&gt;using a non-documented “feature” of the old system that we’ve now written out."&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Well, that’s &lt;em&gt;exactly&lt;/em&gt; what they did. On Friday, &lt;a title="https://live.sagepay.com/txstatus/txstatus.asp" href="https://live.sagepay.com/txstatus/txstatus.asp"&gt;https://live.sagepay.com/txstatus/txstatus.asp&lt;/a&gt; was returning real-time status for previous payment transactions – and now it’s gone. Vanished. What used to take 500 milliseconds in an automated script now takes a real person 90 seconds or so – including all that lovely horizontal scrolling they have to do.&lt;/p&gt;  &lt;p&gt;Still, all is not lost. If SagePay really do have a clean, new architecture, and full test coverage, and a decent agile process in place, then it should be straightforward to respond to this customer feedback.&lt;strong&gt; Respond to change, instead of following a plan.&lt;/strong&gt; Some tweaks at the presentation layer, maybe a couple of new properties on various view models and controllers, a handful of new methods on the supporting services, and it shouldn’t take long to deliver a product that combines the scalability and security of the new system with a UI that does exactly what the customers need. &lt;/p&gt;  &lt;p&gt;Mat, if you’re reading this, I’d be really interested to hear what you guys did today whilst your support team were running around putting out fires. I’d love to see what your product backlog looks like right now, and how you’re condensing the torrent of feedback into user stories and work items. There’s not enough sharing in this industry, and if you and your team can be as open about things today as you were this time last week, you’ll probably help a whole bunch of people – including me – next time we find ourselves babysitting a tricky launch.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7295454224203070190-326293442142061444?l=dylanbeattie.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/dylanbeattie/~4/Wgxt7GYlCtg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://dylanbeattie.blogspot.com/feeds/326293442142061444/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7295454224203070190&amp;postID=326293442142061444" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/326293442142061444?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7295454224203070190/posts/default/326293442142061444?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/dylanbeattie/~3/Wgxt7GYlCtg/if-it-aint-broke-why-good-code-doesnt.html" title="“If It Ain’t Broke…” – Why Good Code Doesn’t Guarantee Happy Users" /><author><name>Dylan Beattie</name><uri>http://www.blogger.com/profile/06437484057047871824</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_de7B8BtZZIw/TMWYR8F5AxI/AAAAAAAAADk/BmtEcSFPysw/s72-c/image_thumb%5B4%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://dylanbeattie.blogspot.com/2010/10/if-it-aint-broke-why-good-code-doesnt.html</feedburner:origLink></entry></feed>

