<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-5733547231775030285</id><updated>2010-01-30T20:56:01.949+11:00</updated><title type='text'>Mere Code</title><subtitle type='html'>Hacking, Software Collaboration, Testing and Diverse Other Topics of General Interest to the Practicing Programmer</subtitle><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default'/><link rel='alternate' type='text/html' href='http://code.mumak.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default?start-index=26&amp;max-results=25'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://code.mumak.net/atom.xml'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>113</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-8608109106301955376</id><published>2010-01-26T22:13:00.002+11:00</published><updated>2010-01-26T22:17:53.690+11:00</updated><title type='text'>Black out</title><content type='html'>I've been a bit slack and have yet to black out my website or avatar to protest the Australian government's mandatory Internet censorship policy.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In case circumstances prevent me from doing so, please read the &lt;a href="http://www.internetblackout.com.au/"&gt;Internet Blackout Australia&lt;/a&gt; website to see why it's so important. You might also want to read &lt;a href="http://blemings.org/hugh/blog/blosxom.cgi/2010/01/25#20100125a"&gt;Hugh Blemings' well-written thoughts&lt;/a&gt; on the matter.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-8608109106301955376?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/8608109106301955376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=8608109106301955376' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/8608109106301955376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/8608109106301955376'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2010/01/black-out.html' title='Black out'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-7026377911891784894</id><published>2010-01-25T18:16:00.001+11:00</published><updated>2010-01-25T18:17:35.945+11:00</updated><title type='text'>Electronic book reader?</title><content type='html'>On &lt;a href="http://life.mumak.net"&gt;my other blog&lt;/a&gt;, I ask about &lt;a href="http://life.mumak.net/2010/01/electronic-book-reader.html"&gt;electronic book readers&lt;/a&gt;. Recommendations greatly desired.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-7026377911891784894?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/7026377911891784894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=7026377911891784894' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/7026377911891784894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/7026377911891784894'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2010/01/electronic-book-reader.html' title='Electronic book reader?'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-9085047783759028579</id><published>2010-01-05T11:07:00.003+11:00</published><updated>2010-01-05T11:21:29.861+11:00</updated><title type='text'>Python testing goodies</title><content type='html'>Just found out that there's &lt;a href="https://edge.launchpad.net/~subunit/+archive/ppa"&gt;a PPA with the latest releases of a whole bunch of Python testing goodies&lt;/a&gt;, including:&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://launchpad.net/testtools"&gt;testtools&lt;/a&gt; - Extensions to unittest that make real extensions possible&lt;/li&gt;&lt;li&gt;&lt;a href="https://launchpad.net/testresources"&gt;testresources&lt;/a&gt; - Safely re-use expensive resources in tests without paying massive set-up costs&lt;/li&gt;&lt;li&gt;&lt;a href="https://launchpad.net/subunit"&gt;subunit&lt;/a&gt; - Manipulate, exchange and analyze test results without writing code&lt;/li&gt;&lt;li&gt;&lt;a href="https://launchpad.net/testscenarios"&gt;testscenarios&lt;/a&gt; - Run the same tests against many different implementations&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;If you are running Ubuntu 9.10 or later, then &lt;code&gt;sudo add-apt-repository ppa:subunit&lt;/code&gt; will add it to your apt sources.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We're starting to grow a lot of useful, small testing tools that become even more useful when combined. I really like the "small pieces, loosely joined" approach, but sometimes that can make deployment &amp;amp; dependency management a colossal pain. Happily, Ubuntu, &lt;a href="http://rbtcollins.wordpress.com/"&gt;Rob&lt;/a&gt; and &lt;a href="https://edge.launchpad.net/ubuntu/+ppas"&gt;Launchpad PPAs&lt;/a&gt; to the rescue.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-9085047783759028579?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/9085047783759028579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=9085047783759028579' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/9085047783759028579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/9085047783759028579'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2010/01/python-testing-goodies.html' title='Python testing goodies'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-8878173265240028583</id><published>2009-12-16T09:55:00.002+11:00</published><updated>2009-12-16T10:19:56.667+11:00</updated><title type='text'>testtools 0.9.2 released</title><content type='html'>I've just released &lt;a href="http://pypi.python.org/pypi/testtools/0.9.2"&gt;testtools 0.9.2&lt;/a&gt;, which I firmly believe is the best &lt;a href="https://launchpad.net/testtools"&gt;testtools&lt;/a&gt; release ever. Thanks very much to &lt;a href="http://rbtcollins.wordpress.com/"&gt;Robert Collins&lt;/a&gt; and &lt;a href="http://pybites.blogspot.com/"&gt;Benjamin Peterson&lt;/a&gt; for making it so.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For the last few releases, we've been working on being more than just a simple aggregation of existing unit testing best practices and tried to do our own experimental extensions.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;These extensions aren't actually all that exciting by themselves. We haven't added better logging support or new types of outcomes or test replay or smart rendering of error results or anything like that. I'm pretty sure testtools will never do those sorts of things.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Rather, the extensions we've added are designed to let &lt;i&gt;you&lt;/i&gt; do that, and then share &lt;i&gt;your&lt;/i&gt; extensions with other people without getting them into the standard library's base &lt;code&gt;unittest&lt;/code&gt; classes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you are using testtools, you can change the way &lt;code&gt;TestCase.run()&lt;/code&gt; works without overriding run and without figuring out how to safely call user code. You can handle exceptions raised from tests however you'd like — again not needing to change &lt;code&gt;TestCase.run()&lt;/code&gt;. You can add new, rich types of assertions without having to modify some base class somewhere. You can store information on a test object that can be used by a sufficiently smart &lt;code&gt;TestResult&lt;/code&gt;, which can be handy if you want to see, say, access logs for all failed tests.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Of course, all this starts to get really powerful when testtools is in the standard library, and all of the other major Python test frameworks inherit from it: nose, py.test, zope.testing and Twisted Trial.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Even so, it's worth switching to testtools today, just for the assertion logic alone. All it takes is changing the base class of your test cases to &lt;code&gt;testtools.TestCase&lt;/code&gt;. If your test framework supports running standard Python unit tests, it'll support testtools.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-8878173265240028583?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/8878173265240028583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=8878173265240028583' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/8878173265240028583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/8878173265240028583'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/12/testtools-092-released.html' title='testtools 0.9.2 released'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-1282121015269802629</id><published>2009-11-28T03:50:00.003+11:00</published><updated>2009-11-28T04:07:46.098+11:00</updated><title type='text'>Lean Lean</title><content type='html'>Ever been confused by people saying "this is Lean" or "that is Lean" or "we should actually be using a cyclometric value-stream set-based burndown kanban for this"? I have, so I thought I'd write a quick pared-down cheat sheet to explain exactly what Lean is. A lean version of Lean, if you will.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At the very least, Lean is seven principles which, we're told, we should apply to making software.&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Eliminate waste&lt;/li&gt;&lt;li&gt;Amplify learning&lt;/li&gt;&lt;li&gt;Decide as late as possible&lt;/li&gt;&lt;li&gt;Deliver as fast as possible&lt;/li&gt;&lt;li&gt;Empower the team&lt;/li&gt;&lt;li&gt;Build integrity in&lt;/li&gt;&lt;li&gt;See the whole&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;The first principle is fundamental.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;List taken from &lt;a href="http://www.poppendieck.com/"&gt;Lean Software Development&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-1282121015269802629?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/1282121015269802629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=1282121015269802629' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/1282121015269802629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/1282121015269802629'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/11/lean-lean.html' title='Lean Lean'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-7400062221229974167</id><published>2009-11-27T20:12:00.003+11:00</published><updated>2009-11-27T22:50:54.776+11:00</updated><title type='text'>How to ask an open source project to do something</title><content type='html'>This isn't exhaustive, but I think there are two ways to ask an open source project to do something:&lt;div&gt;&lt;ol&gt;&lt;li&gt;I want X. You should do X.&lt;/li&gt;&lt;li&gt;I want X. How can I help do X?&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;I have no data, but I think that asking the second way is what makes open source actually work.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-7400062221229974167?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/7400062221229974167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=7400062221229974167' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/7400062221229974167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/7400062221229974167'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/11/how-to-ask-open-source-project-to.html' title='How to ask an open source project to do something'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-6729277015900487726</id><published>2009-11-26T20:22:00.002+11:00</published><updated>2009-11-26T22:16:49.008+11:00</updated><title type='text'>To do: To dos (Palm Prē)</title><content type='html'>You might already know that I have a lot of &lt;span style="font-style: italic;"&gt;lists&lt;/span&gt; on my computer. I may have mentioned once or twice that I have such lists. These lists are connected to a certain popular productivity system which isn't really about productivity and is a little bit like a cult.&lt;br /&gt;&lt;br /&gt;I might have also mentioned that I've been longing for a "smart" phone, partly so I can have these lists with me at all times, to clutch at reflexively like some Popish talisman.&lt;br /&gt;&lt;br /&gt;Now that I have a Palm Prē I have lists and a smart phone, and yet one does not know the other. I am at a loss as to how to get my lists — line-separated text files on my laptop — onto the Tasks application on the Palm. Even then, once they are on the Palm, I have no idea as to how to get them synchronized with something I can edit from my laptop.&lt;br /&gt;&lt;br /&gt;Any ideas?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-6729277015900487726?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/6729277015900487726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=6729277015900487726' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/6729277015900487726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/6729277015900487726'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/11/to-do-to-dos-palm-pre.html' title='To do: To dos (Palm Prē)'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-4483019994524041747</id><published>2009-11-24T23:31:00.002+11:00</published><updated>2009-11-24T23:36:24.227+11:00</updated><title type='text'>Palm Prē reflections</title><content type='html'>I got a Palm Prē yesterday. Here are some initial thoughts.&lt;div&gt;&lt;ul&gt;&lt;li&gt;I like the feel of the physical device&lt;/li&gt;&lt;li&gt;The keyboard is small&lt;/li&gt;&lt;li&gt;Camera is useless for taking photos of receipts&lt;/li&gt;&lt;li&gt;The gesture UI is great&lt;/li&gt;&lt;li&gt;The Mail application shows individual emails, rather than GMail-style conversations. Lame.&lt;/li&gt;&lt;li&gt;I don't know how to get my lists out of text files on my computer and onto the Palm&lt;/li&gt;&lt;li&gt;I don't know actually know anything about syncing from the Palm&lt;/li&gt;&lt;li&gt;I still don't regret not getting an iPhone&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-4483019994524041747?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/4483019994524041747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=4483019994524041747' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/4483019994524041747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/4483019994524041747'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/11/palm-pre-reflections.html' title='Palm Prē reflections'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-7710940222452990092</id><published>2009-11-23T22:48:00.002+11:00</published><updated>2009-11-23T23:00:42.134+11:00</updated><title type='text'>UDS</title><content type='html'>&lt;div&gt;I'm back in London after a mammoth two weeks travelling the globe bringing &lt;a href="https://launchpad.net"&gt;Launchpad&lt;/a&gt; joy to its four corners.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First up I went to Mooloolaba, Australia. If you're Australian, you probably know how to pronounce it. If you aren't, you'll probably never get it. Sorry.&lt;/div&gt;&lt;div&gt;I was there with the Canonical Bazaar team and some other Launchpadders, talking about their next few months of development. They are going to be focusing on helping Launchpad and the Ubuntu platform team work on our daily build initiative. Hmm. I really need a place to link to for that last one, don't I?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Mooloolaba is a beautiful place to be in November. If you are thinking of giving me something for Christmas, consider a holiday apartment there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After Mooloolaba, I crossed the Pacific to reach Dallas, home of the twenty-eight lane highway. I didn't really get into the city that much, but man, &lt;a href="https://wiki.ubuntu.com/UDS-L?action=show&amp;amp;redirect=UDS"&gt;UDS&lt;/a&gt; was great.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Most of the people there are directly involved in Ubuntu development. It's such a joy to see so many people from all over the world come together to work on Ubuntu, and an honour to think that I have a place in that work.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I spent most of the conference flitting from room to room, going to sessions about the Ubuntu development process, &lt;a href="https://wiki.ubuntu.com/DailyBuilds"&gt;daily builds&lt;/a&gt; and the &lt;a href="https://wiki.ubuntu.com/SoftwareCenter"&gt;Software Centre&lt;/a&gt;. Occasionally, I cheated a bit and went to a random session that interested me. Mostly it was about &lt;a href="https://launchpad.net/quickly"&gt;Quickly&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As a Launchpad developer, one of the most exciting things about this UDS was seeing that Ubuntu developers have started building &lt;a href="https://help.launchpad.net/API/Uses"&gt;their own tools around Launchpad using our API&lt;/a&gt;. Many of these tools are things we'd love to integrate with the main web app, but many are things that are &lt;i&gt;so&lt;/i&gt; Ubuntu policy specific that we're happy to leave them outside. After all, this is exactly&lt;/div&gt;&lt;div&gt;what the API is about.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I did a short plenary session where I hacked up &lt;a href="https://code.edge.launchpad.net/~jml/+junk/bugstats"&gt;an API script&lt;/a&gt; using &lt;a href="https://help.launchpad.net/API/launchpadlib"&gt;launchpadlib&lt;/a&gt; and demonstrated it live. After the presentation, many people came up to me and started talking about their API-using programs and their experience making them. The amount of interest really surprised me.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I also ran a couple of workshop / discussions. The first was on improving Launchpad for API use, which was a bit disorganized, since I didn't realize I was supposed to be running it. The second was on getting started with Launchpad hacking.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For the "Getting started with Launchpad hacking" session, I passed around a USB stick, and asked the audience for an API within Launchpad to expose. &lt;a href="http://mdzlog.alcor.net/"&gt;mdz&lt;/a&gt; suggested "blueprints", so I went to expose the 'drafter' element of a specification. In front of a room full of people. Sheesh.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you think pair programming is hard (it is, and if you think it isn't you are either doing it wrong or you have extremely helpful colleagues), programming in front of a room full of people is harder.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Still, we managed to actually expose the API and &lt;a href="https://code.edge.launchpad.net/~jml/launchpad/expose-blueprints/+merge/15060"&gt;propose the branch for merging&lt;/a&gt; with only a little bit of evil.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The point of the session was to get people set up with Launchpad development environments, to show them how to even begin to expose a method over the API but even more than that, to give people a little push into just giving Launchpad development a try. By blundering my way into a valid patch, I think maybe we succeeded.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now UDS is over and I'm back in London, jetlagged and exhausted to be sure, but genuinely happy about the plans we have for Launchpad development, and eager to begin to make them happen.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-7710940222452990092?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/7710940222452990092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=7710940222452990092' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/7710940222452990092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/7710940222452990092'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/11/uds.html' title='UDS'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-3406548594265618981</id><published>2009-11-14T00:26:00.003+11:00</published><updated>2009-11-14T00:26:49.571+11:00</updated><title type='text'>Evil Overlord talks</title><content type='html'>My "Hack Like an Evil Overlord" talks are now linked from my &lt;a href="http://mumak.net/stuff"&gt;stuff&lt;/a&gt; page.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-3406548594265618981?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/3406548594265618981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=3406548594265618981' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/3406548594265618981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/3406548594265618981'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/11/evil-overlord-talks.html' title='Evil Overlord talks'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-8144946741495454609</id><published>2009-11-11T18:57:00.002+11:00</published><updated>2009-11-11T19:16:31.791+11:00</updated><title type='text'>Tests: Costs and Benefits</title><content type='html'>I like unit testing a lot. I've recently been thinking about whether it really is everything that advocates like myself make it out to be. I'm still thinking, but I reckon that language has something to do with it, and that I wouldn't like TDD so much if I were writing in Haskell. Maybe.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, here are the benefits of unit testing, without justification or explanation:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Easier to maintain code&lt;/li&gt;&lt;li&gt;Avoiding regressions&lt;/li&gt;&lt;li&gt;Make API clearer, both by describing it and by encouraging contracts.&lt;/li&gt;&lt;li&gt;Confidence in changes to code&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;For new contributors, there are other benefits:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Confidence in changes to code&lt;/li&gt;&lt;li&gt;Confidence in the validity of your own patch&lt;/li&gt;&lt;li&gt;Mechanism for exploring internal system behaviour&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Some of the costs are:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Maintaining tests&lt;/li&gt;&lt;li&gt;Caring about the performance of tests&lt;/li&gt;&lt;li&gt;Running the tests&lt;/li&gt;&lt;li&gt;Debugging tests&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;For new contributors, there are other costs:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Finding tests&lt;/li&gt;&lt;li&gt;Figuring out how to run tests&lt;/li&gt;&lt;li&gt;Figuring out how to write tests&lt;/li&gt;&lt;li&gt;Learn unit testing&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Is this fair? Is this clear? And exactly where was that post by that guy about unit testing being overrated?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On a half-related and slightly exasperated note, many of the conversations I've been having recently have been about costs and benefits. What happened to doing something because it was the right thing?&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-8144946741495454609?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/8144946741495454609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=8144946741495454609' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/8144946741495454609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/8144946741495454609'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/11/tests-costs-and-benefits.html' title='Tests: Costs and Benefits'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-7442666575343354922</id><published>2009-10-28T03:46:00.002+11:00</published><updated>2009-10-28T04:04:28.947+11:00</updated><title type='text'>Raise your standards</title><content type='html'>I gatecrashed LugRadio Live last Saturday and went to an excellent talk by Matthew Paul Thomas about reporting usability problems. Matthew has reported &lt;a href="https://bugs.edge.launchpad.net/launchpad-project/+bugs?field.searchtext=&amp;amp;orderby=-importance&amp;amp;search=Search&amp;amp;field.status:list=NEW&amp;amp;field.status:list=INCOMPLETE_WITH_RESPONSE&amp;amp;field.status:list=INCOMPLETE_WITHOUT_RESPONSE&amp;amp;field.status:list=INVALID&amp;amp;field.status:list=WONTFIX&amp;amp;field.status:list=CONFIRMED&amp;amp;field.status:list=TRIAGED&amp;amp;field.status:list=INPROGRESS&amp;amp;field.status:list=FIXCOMMITTED&amp;amp;field.status:list=FIXRELEASED&amp;amp;assignee_option=any&amp;amp;field.assignee=&amp;amp;field.bug_reporter=mpt&amp;amp;field.bug_supervisor=&amp;amp;field.bug_commenter=&amp;amp;field.subscriber=&amp;amp;field.omit_dupes.used=&amp;amp;field.omit_dupes=on&amp;amp;field.has_patch.used=&amp;amp;field.has_cve.used=&amp;amp;field.tag=&amp;amp;field.tags_combinator=ANY"&gt;well over a thousand bugs against Launchpad itself&lt;/a&gt; (many of which &lt;a href="https://bugs.edge.launchpad.net/launchpad-project/+bugs?field.searchtext=&amp;amp;orderby=-importance&amp;amp;search=Search&amp;amp;field.status:list=FIXCOMMITTED&amp;amp;field.status:list=FIXRELEASED&amp;amp;assignee_option=any&amp;amp;field.assignee=&amp;amp;field.bug_reporter=mpt&amp;amp;field.bug_supervisor=&amp;amp;field.bug_commenter=&amp;amp;field.subscriber=&amp;amp;field.omit_dupes.used=&amp;amp;field.omit_dupes=on&amp;amp;field.has_patch.used=&amp;amp;field.has_cve.used=&amp;amp;field.tag=&amp;amp;field.tags_combinator=ANY"&gt;have been fixed&lt;/a&gt;) so he knows something about the subject.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Matthew gave six pointers on how to report usability problems, but for me the single most striking one was this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;b&gt;Raise your standards&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;When you are using an application with the aim of improving its usability, you need to shed all of your tolerance and forget those many workarounds you've learned. Drum your fingers impatiently while you wait for something to load. Think of how this would look if you were showing it to a sceptical friend.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The point struck me because so many times as an application &lt;i&gt;developer&lt;/i&gt; I've thought to myself "it's good enough" or "it will work for now". Really though, that's not good enough. I should work until the thing I've added is invisible, or at least fun to use. I need to raise my standards.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Having raised one's standards, the trick is then to avoid the traps of perfectionism. Do you have any thoughts on how to walk the road, avoiding the pitfalls, standards held high?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-7442666575343354922?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/7442666575343354922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=7442666575343354922' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/7442666575343354922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/7442666575343354922'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/10/raise-your-standards.html' title='Raise your standards'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-2363169978576622343</id><published>2009-10-20T22:50:00.002+11:00</published><updated>2009-10-20T23:02:11.777+11:00</updated><title type='text'>Bug squashing sprints</title><content type='html'>Every time somebody asks me what I think we should do for a sprint, I try to suggest "fix as many bugs as possible".&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Each of the Launchpad teams gets together in a single location for a week long "sprint" fairly regularly. Maybe each team has two sprints a year.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Often these sprints end up being long talking sessions where designs for features are thrashed out. That's great and all, and sprints are a rare opportunity to do that, but often the design work goes unused for months while the team deals with the work already on its collective plate.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sometimes these sprints have the whole team working (i.e. coding) toward a single milestone, be it a release or a major feature. These sprints are fun, but they've been quite rare for Launchpad. (Bazaar had a great one in Brisbane earlier this year).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I'd love to see is a sprint where people fixed as many bugs as possible. Perhaps as a product strategist, I ought to be advocating higher-level visions and responding to the market and so forth, rather than saying "fix lots of bugs". But I don't think so, at least, not yet.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Fixing as many bugs as we can in a fixed time frame will make many users happy, since behind each bug is a user in pain. It will make us happy as a team, since a vastly dropped bug count will make us feel less overwhelmed and will feel like a concrete achievement. It's an easy sprint to measure the success of, and my hunch is that it would be a fun sprint too. It's also substantially different to what we normally do, which adds to the fun.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What do you think? I'd love to hear from people in community-driven open source projects, as well as people within Canonical who aren't in Launchpad. Maybe we're missing something that others know about.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-2363169978576622343?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/2363169978576622343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=2363169978576622343' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/2363169978576622343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/2363169978576622343'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/10/bug-squashing-sprints.html' title='Bug squashing sprints'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-7350864700495649504</id><published>2009-10-15T21:42:00.003+11:00</published><updated>2009-10-15T21:59:54.584+11:00</updated><title type='text'>Command line apps</title><content type='html'>Back in the day, I used to want to use &lt;a href="http://twistedmatrix.com/projects/core/documentation/howto/options.html"&gt;twisted.python.usage&lt;/a&gt; for all of my command-line apps. It's a fairly nice &lt;a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.python.usage.html"&gt;API&lt;/a&gt; &amp;amp; a good way of writing code.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Since I started writing Bazaar plugins though, I've fallen in love with Bazaar's command interface. &lt;a href="https://code.edge.launchpad.net/~jkakar"&gt;Jamu&lt;/a&gt; has too, so he wrote &lt;a href="https://edge.launchpad.net/commandant"&gt;Commandant&lt;/a&gt;. I don't really understand it though, which is mostly for lack of trying.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Michael turned our internal EC2-using testing tool into a bzr-a-like app &lt;a href="http://bazaar.launchpad.net/~launchpad-pqm/launchpad/stable/annotate/head:/lib/devscripts/ec2test/builtins.py"&gt;using the Bazaar APIs&lt;/a&gt;. There's a bit of duplication, but it works pretty well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Bazaar developers are aware that their command-line interface code rocks and that it's too closely bound to Bazaar. I'm not sure whether anyone has filed bugs about it or not, but here's what I actually want:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;The subcommand interface, e.g. "bzr foo"&lt;/li&gt;&lt;li&gt;Option parsing&lt;/li&gt;&lt;li&gt;Help&lt;/li&gt;&lt;li&gt;Command aliasing&lt;/li&gt;&lt;li&gt;Error handling&lt;/li&gt;&lt;li&gt;Progress display&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;There's also a bunch of cool stuff in Bazaar that's useful for a lot of applications, command-line or not.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Registries&lt;/li&gt;&lt;li&gt;Transports&lt;/li&gt;&lt;li&gt;Hooks&lt;/li&gt;&lt;li&gt;Oh yeah, &lt;b&gt;plugins&lt;/b&gt;. (How could I have forgotten this?)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Sometimes I wish projects like Bazaar and Twisted split this sort of stuff out into separate packages. That would probably change the way the packages are maintained, and I don't know whether it would be for better or for worse.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sadly, no moral or action for this post. Just stuff that's been on my mind that I wanted to write down and publish. I'd very much welcome input.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-7350864700495649504?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/7350864700495649504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=7350864700495649504' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/7350864700495649504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/7350864700495649504'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/10/command-line-apps.html' title='Command line apps'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-2581147091234827441</id><published>2009-10-15T20:16:00.002+11:00</published><updated>2009-10-15T20:26:47.355+11:00</updated><title type='text'>Launchpad extensions</title><content type='html'>Launchpad has a pretty awesome &lt;a href="http://edge.launchpad.net/+apidoc"&gt;public API&lt;/a&gt;, implemented using &lt;a href="https://launchpad.net/lazr.restful"&gt;lazr.restful&lt;/a&gt;. I've written a few small scripts for it, and the Launchpad team has a few scripts that they use internally for doing admin tasks.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Ubuntu Platform team does a heap of stuff with the Launchpad API. &lt;a href="http://jameswestby.net/weblog"&gt;James Westby&lt;/a&gt; has been using it to make sure that there's a branch on Launchpad for every single package in Ubuntu.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There's all this great work, but there's been nothing to tie the room together. I've seen hardly any discussion about how to write Launchpad API applications, or how to test them, or how to get &lt;a href="https://launchpad.net/launchpadlib"&gt;launchpadlib&lt;/a&gt; working in GTK+. I haven't even seen much code sharing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, borrowing a trick from Twisted's &lt;a href="https://launchpad.net/tx"&gt;tx&lt;/a&gt; super-project, I've created an '&lt;a href="https://launchpad.net/lpx"&gt;lpx&lt;/a&gt;' project group on Launchpad. Bring it your scripts, your applications, your huddled masses. If you want to know more about the API, look at the &lt;a href="http://help.launchpad.net/API"&gt;API help page&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thanks to &lt;a href="http://markshuttleworth.com"&gt;Mark&lt;/a&gt; for reminding me that this is important.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-2581147091234827441?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/2581147091234827441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=2581147091234827441' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/2581147091234827441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/2581147091234827441'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/10/launchpad-extensions.html' title='Launchpad extensions'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-3977792615495631243</id><published>2009-10-09T20:06:00.002+11:00</published><updated>2009-10-09T20:31:56.417+11:00</updated><title type='text'>Launchpad status now on identi.ca</title><content type='html'>Sometimes, sadly, Launchpad doesn't behave as well as we'd like.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Although we try extremely hard to always be available, and take each instance of downtime (planned or unplanned) as a personal insult, sometimes we're forced to disappoint both our users and ourselves. It's no excuse, of course, but at least we're in &lt;a href="http://www.worldofwarcraft.com/"&gt;good&lt;/a&gt; &lt;a href="https://mail.google.com/"&gt;company&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To make these inevitable interruptions easier to swallow, we've set up &lt;a href="http://identi.ca/launchpadstatus"&gt;identi.ca&lt;/a&gt; and &lt;a href="http://twitter.com/launchpadstatus"&gt;Twitter&lt;/a&gt; accounts that report the Launchpad server statuses, and only the server statuses. We've got people all around the world who are able to update it when things go bump in the night. There's also a link to the identi.ca page in our footer, so you don't have to keep consulting a blog.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thanks very much to &lt;a href="http://www.understated.co.uk/"&gt;Matt Revell&lt;/a&gt; for getting this done.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-3977792615495631243?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/3977792615495631243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=3977792615495631243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/3977792615495631243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/3977792615495631243'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/10/launchpad-status-now-on-identica.html' title='Launchpad status now on identi.ca'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-3411025813324059298</id><published>2009-10-09T05:19:00.002+11:00</published><updated>2009-10-09T05:29:55.962+11:00</updated><title type='text'>Meta-meeting stuff</title><content type='html'>Last week the Launchpad team leads gathered in London and had an absolutely huge meeting. Fifteen or sixteen smart, opinionated &amp;amp; passionate people in a room talking about the next six months of Launchpad development. It was a lot of fun.&lt;br /&gt;&lt;br /&gt;When planning the agenda, Martin Albisetti and I were a little worried about things wandering off track, so we thrashed out a lists of dos &amp;amp; don'ts. I'll blurt them out here, with the really terrible ideas filtered out so I look more clever, and then offer some thoughts on how they worked.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Do&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;be happy with the results of this meeting.&lt;/li&gt;&lt;li&gt;ask questions, especially "why"&lt;/li&gt;&lt;li&gt;be punctual&lt;/li&gt;&lt;li&gt;stay on point&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Don't&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;design features&lt;/li&gt;&lt;li&gt;check your email, i.e. laptops closed&lt;br /&gt;&lt;/li&gt;&lt;li&gt;leave the meeting without being clear&lt;/li&gt;&lt;li&gt;leave the meeting without being happy&lt;/li&gt;&lt;/ul&gt;The "laptops closed" one didn't work so well. It was great for the first couple of days, but by Thursday afternoon there were always people in a corner with those open LCD screens sucking chi out of the room like little dragons of despair.&lt;br /&gt;&lt;br /&gt;The "Don't design features" rule was awesome. The rationale is that feature design leads to long discussions, and that it does a disservice to the many excellent engineers we have who aren't at the meeting and will be actually implementing a feature. At best, it's waste and at worst it's us telling people how to do something that they know how to do better. The clearest sign that it was a good idea came when other people started using it to shut me up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-3411025813324059298?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/3411025813324059298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=3411025813324059298' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/3411025813324059298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/3411025813324059298'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/10/meta-meeting-stuff.html' title='Meta-meeting stuff'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-5538618958290327740</id><published>2009-10-08T02:44:00.004+11:00</published><updated>2009-10-08T03:01:53.731+11:00</updated><title type='text'>Talking Time</title><content type='html'>I've been working on the Launchpad team for a while, with most of that time being in Australia. Others in the team are in the US (red states &amp;amp; blue states), the UK, Germany, Brazil, Canada, New Zealand, Serbia, Lithuania and Thailand.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here are some tips I've picked up for smoother online conversations, particularly around scheduling.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Don't say "summer" or "fall". Say the month, or the range of months.&lt;/li&gt;&lt;li&gt;Say "my morning" rather than "the morning".&lt;/li&gt;&lt;li&gt;Use 24-hour time.&lt;/li&gt;&lt;li&gt;In real-time conversations, say "in 2 hours time" rather than "at 10".&lt;/li&gt;&lt;li&gt;Always include the timezone. Avoid using local abbreviations (e.g. PST), instead use offset from UTC.&lt;/li&gt;&lt;li&gt;Better still, just give the time in UTC.&lt;/li&gt;&lt;li&gt;Know your UTC offset.&lt;/li&gt;&lt;li&gt;Use a timezone-aware &lt;a href="http://timeanddate.com/worldclock/meeting.html"&gt;meeting planner&lt;/a&gt;. You'll get the arithmetic wrong otherwise.&lt;/li&gt;&lt;li&gt;Say "Oct 7" rather than 10/7 or 7/10. Everyone speaks English, but not everyone uses your dialect.&lt;/li&gt;&lt;li&gt;The time that you end a meeting is more important than when you start it. Thoughtfully consider the timezones of other attendees when you are planning for &amp;amp; participating in meetings.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Violating these rules isn't a big deal, since people can generally figure out what you mean. Following them, however, can speed things along and sometimes even avoid tedious conversations.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-5538618958290327740?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/5538618958290327740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=5538618958290327740' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/5538618958290327740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/5538618958290327740'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/10/talking-time.html' title='Talking Time'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-6063518981844975302</id><published>2009-09-15T16:16:00.002+10:00</published><updated>2009-09-15T16:24:09.189+10:00</updated><title type='text'>Colon full of cookie</title><content type='html'>Launchpad does translations. You can register a project on Launchpad and use Launchpad to translate your software into a zillion other languages. We've even got funky tools to take the translations that people do on the web and commit them straight to your branch.&lt;br /&gt;&lt;br /&gt;As an ignorant Anglophonic monoglot, I've never really looked into Launchpad Translations. Software is already written in my language, and I can't help translate it into my language. There has been no reason for me to look at it... until today.&lt;br /&gt;&lt;br /&gt;Barry Warsaw, hacker extraordinaire, has started a project called &lt;a href="https://launchpad.net/colon-full-of-cookie"&gt;I have a colon full of cookie&lt;/a&gt;. This project aims to translate the phrase "I have a colon full of cookie" into as many languages as possible. Note here that "colon" is the organ, not the punctuation mark.&lt;br /&gt;&lt;br /&gt;OK, time to bust out my Latin lexicon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-6063518981844975302?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/6063518981844975302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=6063518981844975302' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/6063518981844975302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/6063518981844975302'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/09/colon-full-of-cookie.html' title='Colon full of cookie'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-1352485748808662573</id><published>2009-09-14T18:49:00.003+10:00</published><updated>2009-09-14T19:03:37.174+10:00</updated><title type='text'>Layers are terrible</title><content type='html'>When I talk about testing frameworks, I often mention Zope layers and say they are terrible. Some people have asked me for details on their terror and for justification of my opinion.&lt;br /&gt;&lt;br /&gt;Here's all I've got. It's based on my experiences using layers with Zope 3.2 in Launchpad.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. Layers have unnecessary magic&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A layer can subclass another layer, which is fine. Subclassing means that your new, derived layer rests on top of the old, base layer.&lt;br /&gt;&lt;br /&gt;When you define a derived layer though, you don't call the base layer's methods yourself, like you would for any other Python subclass. Why not? Because zope.testing magically up-calls the base layer's methods for you.&lt;br /&gt;&lt;br /&gt;Yuck.&lt;br /&gt;&lt;br /&gt;The upshot is that you write non-standard Python that confuses people not familiar with zope.testing. Also, you have no way of &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; calling the base methods, which is unfairly restrictive.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. Layers are combined through inheritance&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Each unit test is in a single layer. If you want a unit test to have the set up and tear down provided by layer A &lt;i&gt;and&lt;/i&gt; the set up and tear down of layer B, you have to define a wholly new layer C that subclasses both A and B.&lt;br /&gt;&lt;br /&gt;The layer C doesn't really mean anything other than "A and B". It doesn't really deserve a name, but it has to have one, since it has to be a new class.&lt;br /&gt;&lt;br /&gt;Since layers are often used to share expensive resources between tests, you end up with a binary explosion of layer subclasses, as you move toward needing one for every subset of available resources.&lt;br /&gt;&lt;br /&gt;This adds code and thus maintenance work, and is actually less clear than simply declaring that a test uses layers A and B.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. Layers are implemented badly&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Layers are all about changing the way a test is run. They supplement the run with extra work to establish a known base state for the test.&lt;br /&gt;&lt;br /&gt;If you think about it, the stuff that's required to run a test is a property of the test.&lt;br /&gt;&lt;br /&gt;Python's &lt;code&gt;unittest&lt;/code&gt; module recognizes this. One of the few public methods of a &lt;code&gt;TestCase&lt;/code&gt; object is its &lt;code&gt;run()&lt;/code&gt; method. &lt;code&gt;run()&lt;/code&gt; is also a method of &lt;code&gt;TestSuite&lt;/code&gt;. This means that if you want to customize the way a test or a group of tests is run, you should override / re-implement the &lt;code&gt;run()&lt;/code&gt; method.&lt;br /&gt;&lt;br /&gt;Layers don't do this. Instead they change the way tests are gathered, the way they are reported &lt;i&gt;and&lt;/i&gt; the way they are run. This means tests that rely on layers can only be run with the Zope test runner, and not with nose or trial or what have you.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. Layers solve too many problems&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Layers are not simply a way of sharing expensive resources between tests, they are also a way of using resources that cannot be torn down.&lt;br /&gt;&lt;br /&gt;The implementation does this by detecting that a layer cannot be torn down, then spawning a new process to run the rest of the tests in.&lt;br /&gt;&lt;br /&gt;It kind of sucks to have things that cannot be torn down in process, and it definitely sucks to conflate resource sharing with odd subprocess management.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;5. Layers are not Zopish&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;As far as I can tell, one of the themes of Zope 3 is small, interchangeable pieces loosely joined together.&lt;br /&gt;&lt;br /&gt;Layers seem to be something that could have been done much better using the Zope component architecture. Perhaps they could give &lt;code&gt;getUtility&lt;/code&gt; some practical purpose in life.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What then?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;As much as I hate to say so, I don't think there's much hope for layers as a concept. One is probably better served by replacing one's existing layers with &lt;a href="https://launchpad.net/testresources"&gt;testresources&lt;/a&gt;. It looks like it takes &lt;a href="https://bugs.edge.launchpad.net/launchpad-foundations/+bug/419691/comments/2"&gt;quite a lot of work to do so&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;That's it. Five reasons and a lot of paragraphs. Please let me know if I've made mistakes, or if newer versions of zope.testing are better. Also, please gently correct me if I've left the path of &lt;a href="http://jcalderone.livejournal.com/47657.html"&gt;civility and common courtesy&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-1352485748808662573?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/1352485748808662573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=1352485748808662573' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/1352485748808662573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/1352485748808662573'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/09/layers-are-terrible.html' title='Layers are terrible'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-6721545451752263135</id><published>2009-09-05T17:41:00.003+10:00</published><updated>2009-09-05T17:43:46.146+10:00</updated><title type='text'>Launchpad on Karmic!</title><content type='html'>Thanks almost entirely to &lt;a href="https://launchpad.net/%7Emaxb"&gt;maxb&lt;/a&gt; &amp;amp; &lt;a href="https://launchpad.net/%7Ewgrant"&gt;wgrant&lt;/a&gt;, I can now hack on &lt;a href="http://dev.launchpad.net/LaunchpadOnKarmic"&gt;Launchpad in Karmic&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This is great news for me, since it means I can ditch the chroot I was using. Check out the &lt;a href="http://dev.launchpad.net"&gt;dev wiki&lt;/a&gt; for more details.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-6721545451752263135?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/6721545451752263135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=6721545451752263135' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/6721545451752263135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/6721545451752263135'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/09/launchpad-on-karmic.html' title='Launchpad on Karmic!'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-3580007858402289555</id><published>2009-09-04T16:57:00.002+10:00</published><updated>2009-09-04T17:13:57.431+10:00</updated><title type='text'>Active reviews, again</title><content type='html'>You might remember I was really excited about the first version of the active reviews page, since it let me see at a glance the code reviews I needed to do, the ones I was waiting on, and reviews I could do if I felt like it. At the time, this was really important, since it's the first time I've seen a code collaboration tool orient itself towards me actually doing things. It's certainly a first for Launchpad.&lt;br /&gt;&lt;br /&gt;Tim has recently landed a few changes to the page that aren't quite as revolutionary, but follow the same lines of thinking.&lt;br /&gt;&lt;br /&gt;The one I want to mention is putting all the branches that are approved for landing onto the active reviews page. Every branch that's approved to land and hasn't yet landed is actually waste, it's an improvement that's sitting around gathering dust and waiting for someone to push a button. It's like a winning lottery ticket stuck to your fridge because you're too lazy to cash it in. We think it's so important that we've put these at the top of the list.&lt;br /&gt;&lt;br /&gt;You can take a look at the active reviews pages for:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://code.edge.launchpad.net/%7Ejml/+activereviews"&gt;Jonathan Lange&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://code.edge.launchpad.net/%7Ejml/launchpad/+activereviews"&gt;Jonathan Lange in Launchpad&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://code.edge.launchpad.net/launchpad/+activereviews"&gt;Launchpad&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://code.edge.launchpad.net/people/+me/+activereviews"&gt;Yourself&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Now if you'll excuse me, I have branches to land.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-3580007858402289555?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/3580007858402289555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=3580007858402289555' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/3580007858402289555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/3580007858402289555'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/09/active-reviews-again.html' title='Active reviews, again'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-5333455981400100416</id><published>2009-09-01T18:27:00.002+10:00</published><updated>2009-09-01T18:37:59.880+10:00</updated><title type='text'>Slow tests</title><content type='html'>&lt;a href="http://www.advogato.org/person/robertc/"&gt;Robert Collins&lt;/a&gt; of &lt;a href="http://bazaar-vcs.org"&gt;Bazaar&lt;/a&gt;, recently blogged about the &lt;a href="http://www.advogato.org/person/robertc/diary/113.html"&gt;cost of slow tests&lt;/a&gt;. I couldn't agree more.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://launchpad.net"&gt;Launchpad&lt;/a&gt; has a very slow test suite. It takes upwards of five hours to get a change into &lt;a href="https://code.launchpad.net/%7Elaunchpad-pqm/launchpad/stable"&gt;our "known good" branch&lt;/a&gt;. It's been a source of pain for the team for years, and now that Launchpad is Free Software, it's becoming a pain to new contributors.&lt;br /&gt;&lt;br /&gt;We've tried a few things to deal with it, none of them great. First up, we've got  a tool for running the test suite on EC2 instances. It's nice, but it's still too slow. I've written a "&lt;a href="https://dev.launchpad.net/FasterTests"&gt;faster tests&lt;/a&gt;" spec outlining some of the options we have; but specs never got software written. Likewise, there are a bunch of bugs flagged as &lt;a href="https://bugs.edge.launchpad.net/launchpad-project/+bugs?field.tag=build-infrastructure"&gt;build-infrastructure&lt;/a&gt;, many of which address the slow test sped. We also have a rotating "&lt;a href="https://dev.launchpad.net/BuildEngineer"&gt;Build Engineer&lt;/a&gt;" position within the team to address those bugs.&lt;br /&gt;&lt;br /&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class=" on down" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;It's probably not enough though. From watching Rob's blog posts, and the emails to the Bazaar mailing list, I think that what Launchpad really needs is someone with a passion for solving the problem (i.e. making Launchpad hacking fun) who is willing to lead the way, and a full commitment from the rest of the team for getting the runtime down and keeping it there.&lt;br /&gt;&lt;br /&gt;More on this later.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-5333455981400100416?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/5333455981400100416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=5333455981400100416' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/5333455981400100416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/5333455981400100416'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/09/slow-tests.html' title='Slow tests'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-8406315406716606689</id><published>2009-07-26T11:18:00.002+10:00</published><updated>2009-07-26T11:22:15.756+10:00</updated><title type='text'>Twisted &amp; Monads</title><content type='html'>On Thursday I spoke at fp-syd about &lt;a href="http://static.mumak.net/Twisted-Monads.pdf"&gt;Twisted and monads&lt;/a&gt;. All I have is the slides. If you'd like, I can write up the paper.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-8406315406716606689?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/8406315406716606689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=8406315406716606689' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/8406315406716606689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/8406315406716606689'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/07/twisted-monads.html' title='Twisted &amp; Monads'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5733547231775030285.post-8655058952781613840</id><published>2009-07-21T15:47:00.002+10:00</published><updated>2009-07-21T15:53:54.019+10:00</updated><title type='text'>Launchpad now fully open sourced</title><content type='html'>&lt;a href="https://launchpad.net"&gt;Launchpad&lt;/a&gt; has been &lt;a href="http://blog.canonical.com/?p=192"&gt;open sourced&lt;/a&gt;. That includes Soyuz and Codehosting.&lt;br /&gt;&lt;br /&gt;I'm now a full-time free software hacker. Squee!&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a href="http://www.markshuttleworth.com/"&gt;Mark&lt;/a&gt; for making the call, and to &lt;a href="http://www.red-bean.com/kfogel/"&gt;Karl&lt;/a&gt; for being the flux capacitor of the whole operation, humming along as we've built up to 1.21 gigawatts of &lt;span style="font-style: italic;"&gt;freedom power&lt;/span&gt; and burst right through to the future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5733547231775030285-8655058952781613840?l=code.mumak.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/8655058952781613840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5733547231775030285&amp;postID=8655058952781613840' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/8655058952781613840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5733547231775030285/posts/default/8655058952781613840'/><link rel='alternate' type='text/html' href='http://code.mumak.net/2009/07/launchpad-now-fully-open-sourced.html' title='Launchpad now fully open sourced'/><author><name>jml</name><uri>http://www.blogger.com/profile/11400080716012026985</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='06159200095703820658'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>